diff --git a/.gitignore b/.gitignore index cff0e374..55ad4693 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ pubspec.lock .pub-cache/ .pub/ /build/ +/ios/Frameworks/ # Web related lib/generated_plugin_registrant.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index f1799225..98c75fbe 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -56,6 +56,11 @@ android { compileSdkVersion 34 // ndkVersion "24.0.8215888" + buildFeatures { + viewBinding true + dataBinding true + } + sourceSets { main.java.srcDirs += 'src/main/kotlin' } @@ -69,7 +74,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.ejada.hmg" - minSdkVersion 24 + minSdkVersion 26 targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -117,15 +122,16 @@ android { packagingOptions { exclude 'META-INF/proguard/androidx-annotations.pro' -// pickFirst 'lib/x86/libc++_shared.so' -// pickFirst 'lib/x86_64/libc++_shared.so' -// pickFirst 'lib/armeabi-v7a/libc++_shared.so' -// pickFirst 'lib/arm64-v8a/libc++_shared.so' -// pickFirst '**/*.so' + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + pickFirst '**/*.so' } compileOptions { +// coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } @@ -136,13 +142,15 @@ flutter { } dependencies { +// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "com.google.firebase:firebase-messaging:21.0.0" // implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{ // exclude group: 'com.google.protobuf',module: 'protobuf-javalite' // exclude group: 'com.google.protobuf',module: 'protobuf-lite' // }) - implementation 'pub.devrel:easypermissions:0.4.0' + implementation 'pub.devrel:easypermissions:3.0.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' implementation 'com.google.guava:guava:27.0.1-android' @@ -163,11 +171,36 @@ dependencies { // implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11" // implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11' - implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1" - implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" - implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" - - implementation "org.jetbrains.anko:anko-commons:0.10.4" +// implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1" +// implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" +// implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" + + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.retrofit2:adapter-java8:2.4.0' + implementation 'com.google.code.gson:gson:2.8.9' + implementation 'com.google.android.gms:play-services-location:21.3.0' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'androidx.test.ext:junit:1.1.5' + implementation 'com.android.volley:volley:1.2.1' + def room_version = "2.4.0-alpha04" + implementation "androidx.room:room-runtime:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" + implementation 'net.zetetic:android-database-sqlcipher:4.5.2' + implementation 'com.intuit.ssp:ssp-android:1.1.0' + implementation 'com.intuit.sdp:sdp-android:1.1.0' + implementation 'com.github.bumptech.glide:glide:4.12.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + +// implementation "com.mapbox.maps:android:10.16.6" + implementation 'com.mapbox.maps:android:11.3.1' + + implementation files('libs/PenNavUI.aar') + implementation files('libs/Penguin.aar') + implementation files('libs/PenguinRenderer.aar') + +// implementation "org.jetbrains.anko:anko-commons:0.10.4" implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android @@ -177,6 +210,10 @@ dependencies { implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.22' androidTestImplementation "androidx.test:core:1.4.0" + implementation 'com.airbnb.android:lottie:5.2.0' + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.22' } diff --git a/android/app/google-services.json b/android/app/google-services.json index 5806fa5f..3707617c 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -21,7 +21,7 @@ ], "api_key": [ { - "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg" } ], "services": { diff --git a/android/app/libs/PenNavUI.aar b/android/app/libs/PenNavUI.aar new file mode 100644 index 00000000..d423bc11 Binary files /dev/null and b/android/app/libs/PenNavUI.aar differ diff --git a/android/app/libs/Penguin.aar b/android/app/libs/Penguin.aar new file mode 100644 index 00000000..5c789c6f Binary files /dev/null and b/android/app/libs/Penguin.aar differ diff --git a/android/app/libs/PenguinRenderer.aar b/android/app/libs/PenguinRenderer.aar new file mode 100644 index 00000000..b657ac66 Binary files /dev/null and b/android/app/libs/PenguinRenderer.aar differ diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 69cd8026..ab7b2ca4 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -53,4 +53,20 @@ } -dontwarn com.opentok.android.** --dontwarn com.opentok.otc.** \ No newline at end of file +-dontwarn com.opentok.otc.** + +-dontwarn penguin.com.pennav.Model.Navigation.NearLandmark + +-keep,includedescriptorclasses class net.sqlcipher.** { *; } +-keep,includedescriptorclasses interface net.sqlcipher.** { *; } + +-keep class retrofit2.** { *; } +-keep class okhttp3.** { *; } +-dontwarn retrofit2.** + +-keep class com.google.gson.** { *; } +-dontwarn com.google.gson.** + +# Penguin classes +-keep class com.peng.pennavmap.models.** { *; } +-keep class com.peng.pennavmap.db.** { *; } \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b1540644..2856e8f1 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,21 +8,35 @@ FlutterApplication and put your custom class here. --> - - - - + + + + - + - + + + + + + + + + + + + + + + @@ -42,6 +56,7 @@ + @@ -59,13 +74,13 @@ 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 8aa1ef85..df41e342 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -1,21 +1,19 @@ package com.ejada.hmg -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.ContentResolver -import android.media.AudioAttributes -import android.net.Uri -import android.os.Bundle -import android.util.Log +import android.content.Intent +import android.content.pm.PackageManager import android.os.Build +import android.util.Log import android.view.WindowManager import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge import com.ejada.hmg.utils.* import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterFragmentActivity() { + @RequiresApi(Build.VERSION_CODES.O) override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); // Create Flutter Platform Bridge @@ -23,6 +21,7 @@ class MainActivity: FlutterFragmentActivity() { PlatformBridge(flutterEngine, this).create() OpenTokPlatformBridge(flutterEngine, this).create() + PenguinInPlatformBridge(flutterEngine, this).create() // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH) @@ -43,6 +42,25 @@ class MainActivity: FlutterFragmentActivity() { // val time = timeToMillis("04:00:00", "HH:mm:ss") + } + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } + val intent = Intent("PERMISSION_RESULT_ACTION").apply { + putExtra("PERMISSION_GRANTED", granted) + } + sendBroadcast(intent) + + // Log the request code and permission results + Log.d("PermissionsResult", "Request Code: $requestCode") + Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}") + Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}") + } override fun onResume() { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt new file mode 100644 index 00000000..93affaef --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt @@ -0,0 +1,52 @@ +package com.cloud.diplomaticquarterapp +import com.ejada.hmg.MainActivity +import android.os.Build +import android.util.Log +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.penguin.PenguinView +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel + +class PenguinInPlatformBridge( + private var flutterEngine: FlutterEngine, + private var mainActivity: MainActivity +) { + + private lateinit var channel: MethodChannel + + companion object { + private const val CHANNEL = "launch_penguin_ui" + } + + @RequiresApi(Build.VERSION_CODES.O) + fun create() { +// openTok = OpenTok(mainActivity, flutterEngine) + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> + when (call.method) { + "launchPenguin" -> { + print("the platform channel is being called") + val args = call.arguments as Map? + Log.d("TAG", "configureFlutterEngine: $args") + println("args") + args?.let { + PenguinView( + mainActivity, + 100, + args, + flutterEngine.dartExecutor.binaryMessenger, + activity = mainActivity, + channel + ) + } + } + + else -> { + result.notImplemented() + } + } + } + } + +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt new file mode 100644 index 00000000..b308af05 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt @@ -0,0 +1,28 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +import android.Manifest +import android.os.Build + +object PermissionHelper { + + fun getRequiredPermissions(): Array { + val permissions = mutableListOf( + Manifest.permission.INTERNET, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_NETWORK_STATE, + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, +// Manifest.permission.ACTIVITY_RECOGNITION + ) + + // For Android 12 (API level 31) and above, add specific permissions + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above + permissions.add(Manifest.permission.BLUETOOTH_SCAN) + permissions.add(Manifest.permission.BLUETOOTH_CONNECT) + permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS) + } + + return permissions.toTypedArray() + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt new file mode 100644 index 00000000..81f2a6f0 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt @@ -0,0 +1,50 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat + +class PermissionManager( + private val context: Context, + val listener: PermissionListener, + private val requestCode: Int, + vararg permissions: String +) { + + private val permissionsArray = permissions + + interface PermissionListener { + fun onPermissionGranted() + fun onPermissionDenied() + } + + fun arePermissionsGranted(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + permissionsArray.all { + ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED + } + } else { + true + } + } + + fun requestPermissions(activity: Activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ActivityCompat.requestPermissions(activity, permissionsArray, requestCode) + } + } + + fun handlePermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + if (this.requestCode == requestCode) { + val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } + if (allGranted) { + listener.onPermissionGranted() + } else { + listener.onPermissionDenied() + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt new file mode 100644 index 00000000..33765192 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt @@ -0,0 +1,15 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +// PermissionResultReceiver.kt +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class PermissionResultReceiver( + private val callback: (Boolean) -> Unit +) : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false + callback(granted) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt new file mode 100644 index 00000000..c76f9784 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt @@ -0,0 +1,13 @@ +package com.cloud.diplomaticquarterapp.penguin + +enum class PenguinMethod { + // initializePenguin("initializePenguin"), + // configurePenguin("configurePenguin"), + // showPenguinUI("showPenguinUI"), + // onPenNavUIDismiss("onPenNavUIDismiss"), + // onReportIssue("onReportIssue"), + // onPenNavSuccess("onPenNavSuccess"), + onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"), + // navigateToPOI("navigateToPOI"), + // openSharedLocation("openSharedLocation"); +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt new file mode 100644 index 00000000..98245cc9 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt @@ -0,0 +1,97 @@ +package com.cloud.diplomaticquarterapp.penguin + +import android.content.Context +import com.google.gson.Gson +import com.peng.pennavmap.PlugAndPlaySDK +import com.peng.pennavmap.connections.ApiController +import com.peng.pennavmap.interfaces.RefIdDelegate +import com.peng.pennavmap.models.TokenModel +import com.peng.pennavmap.models.postmodels.PostToken +import com.peng.pennavmap.utils.AppSharedData +import okhttp3.ResponseBody +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import android.util.Log + + +class PenguinNavigator() { + + fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) { + val postToken = PostToken(clientID, clientKey) + getToken(mContext, postToken, object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId is+++++++ $PoiId") + + PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId 2is+++++++ $PoiId") + + delegate.onRefByIDSuccess(refID) + + } + + override fun onGetByRefIDError(error: String?) { + delegate.onRefByIDSuccess(error) + } + + }) + + + } + + override fun onGetByRefIDError(error: String?) { + delegate.onRefByIDSuccess(error) + } + + }) + + } + + fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) { + try { + // Create the API call + val purposesCall: Call = ApiController.getInstance(mContext) + .apiMethods + .getToken(postToken) + + // Enqueue the call for asynchronous execution + purposesCall.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful() && response.body() != null) { + try { + response.body()?.use { responseBody -> + val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content + if (responseBodyString.isNotEmpty()) { + val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java) + if (tokenModel != null && tokenModel.token != null) { + AppSharedData.apiToken = tokenModel.token + apiTokenCallBack.onRefByIDSuccess(tokenModel.token) + } else { + apiTokenCallBack.onGetByRefIDError("Failed to parse token model") + } + } else { + apiTokenCallBack.onGetByRefIDError("Response body is empty") + } + } + } catch (e: Exception) { + apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}") + } + } else { + apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code()) + } + } + + override fun onFailure(call: Call, t: Throwable) { + apiTokenCallBack.onGetByRefIDError(t.message) + } + }) + } catch (error: Exception) { + apiTokenCallBack.onGetByRefIDError("Exception during API call: $error") + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt new file mode 100644 index 00000000..9f74103f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt @@ -0,0 +1,321 @@ +package com.cloud.diplomaticquarterapp.penguin + +import android.app.Activity +import android.content.Context +import android.content.Context.RECEIVER_EXPORTED +import android.content.IntentFilter +import android.graphics.Color +import android.os.Build +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.widget.RelativeLayout +import android.widget.Toast +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionHelper +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionManager +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionResultReceiver +import com.ejada.hmg.MainActivity +import com.peng.pennavmap.PlugAndPlayConfiguration +import com.peng.pennavmap.PlugAndPlaySDK +import com.peng.pennavmap.enums.InitializationErrorType +import com.peng.pennavmap.interfaces.PenNavUIDelegate +import com.peng.pennavmap.utils.Languages +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.platform.PlatformView +import com.cloud.diplomaticquarterapp.penguin.PenguinNavigator +import com.peng.pennavmap.interfaces.PIEventsDelegate +import com.peng.pennavmap.interfaces.PILocationDelegate +import com.peng.pennavmap.interfaces.RefIdDelegate +import com.peng.pennavmap.models.PIReportIssue +/** + * Custom PlatformView for displaying Penguin UI components within a Flutter app. + * Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls, + * and `PenNavUIDelegate` for handling SDK events. + */ +@RequiresApi(Build.VERSION_CODES.O) +internal class PenguinView( + context: Context, + id: Int, + val creationParams: Map, + messenger: BinaryMessenger, + activity: MainActivity, + val channel: MethodChannel +) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate { + // The layout for displaying the Penguin UI + private val mapLayout: RelativeLayout = RelativeLayout(context) + private val _context: Context = context + + private val permissionResultReceiver: PermissionResultReceiver + private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION") + + private companion object { + const val PERMISSIONS_REQUEST_CODE = 1 + } + + private lateinit var permissionManager: PermissionManager + + // Reference to the main activity + private var _activity: Activity = activity + + private lateinit var mContext: Context + + lateinit var navigator: PenguinNavigator + + init { + // Set layout parameters for the mapLayout + mapLayout.layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT + ) + + mContext = context + + + permissionResultReceiver = PermissionResultReceiver { granted -> + if (granted) { + onPermissionsGranted() + } else { + onPermissionsDenied() + } + } + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + permissionResultReceiver, + permissionIntentFilter, + RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + permissionResultReceiver, + permissionIntentFilter, + ) + } + + // Set the background color of the layout + mapLayout.setBackgroundColor(Color.RED) + + permissionManager = PermissionManager( + context = mContext, + listener = object : PermissionManager.PermissionListener { + override fun onPermissionGranted() { + // Handle permissions granted + onPermissionsGranted() + } + + override fun onPermissionDenied() { + // Handle permissions denied + onPermissionsDenied() + } + }, + requestCode = PERMISSIONS_REQUEST_CODE, + *PermissionHelper.getRequiredPermissions() + ) + + if (!permissionManager.arePermissionsGranted()) { + permissionManager.requestPermissions(_activity) + } else { + // Permissions already granted + permissionManager.listener.onPermissionGranted() + } + + + } + + private fun onPermissionsGranted() { + // Handle the actions when permissions are granted + Log.d("PermissionsResult", "onPermissionsGranted") + // Register the platform view factory for creating custom views + + // Initialize the Penguin SDK + initPenguin() + + + } + + private fun onPermissionsDenied() { + // Handle the actions when permissions are denied + Log.d("PermissionsResult", "onPermissionsDenied") + + } + + /** + * Returns the view associated with this PlatformView. + * + * @return The main view for this PlatformView. + */ + override fun getView(): View { + return mapLayout + } + + /** + * Cleans up resources associated with this PlatformView. + */ + override fun dispose() { + // Cleanup code if needed + } + + /** + * Handles method calls from Dart code. + * + * @param call The method call from Dart. + * @param result The result callback to send responses back to Dart. + */ + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + // Handle method calls from Dart code here + } + + /** + * Initializes the Penguin SDK with custom configuration and delegates. + */ + private fun initPenguin() { + navigator = PenguinNavigator() + // Configure the PlugAndPlaySDK + val language = when (creationParams["languageCode"] as String) { + "ar" -> Languages.ar + "en" -> Languages.en + else -> { + Languages.en + } + } + Log.d( + "TAG", + "initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}" + ) + PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder() + .setBaseUrl( + creationParams["dataURL"] as String, + creationParams["positionURL"] as String + ) + .setServiceName( + creationParams["dataServiceName"] as String, + creationParams["positionServiceName"] as String + ) + .setClientData( + creationParams["clientID"] as String, + creationParams["clientKey"] as String + ) + .setUserName(creationParams["username"] as String) +// .setLanguageID(Languages.en) + .setLanguageID(language) + .setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean) + .setEnableBackButton(true) +// .setDeepLinkData("deeplink") + .setCustomizeColor("#2CA0AF") + .setDeepLinkSchema("") + .setIsEnableReportIssue(true) + .build() + + // Set location delegate to handle location updates +// PlugAndPlaySDK.setPiLocationDelegate { + // Example code to handle location updates + // Uncomment and modify as needed + // if (location.size() > 0) + // Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show() +// } + + // Set events delegate for reporting issues +// PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() { +// @Override +// public void onReportIssue(PIReportIssue issue) { +// Log.e("Issue Reported: ", issue.getReportType()); +// } +// // Implement issue reporting logic here } +// @Override +// public void onSharedLocation(String link) { +// // Implement Shared location logic here +// } +// }) + + // Start the Penguin SDK + PlugAndPlaySDK.start(mContext, this) + } + + + /** + * Navigates to the specified reference ID. + * + * @param refID The reference ID to navigate to. + */ + fun navigateTo(refID: String) { + try { + if (refID.isBlank()) { + Log.e("navigateTo", "Invalid refID: The reference ID is blank.") + } +// referenceId = refID + navigator.navigateTo(mContext, refID,object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId") + +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "navigateTo Success" +// ) + } + + override fun onGetByRefIDError(error: String?) { + Log.e("navigateTo", "error is penguin view+++++++ $error") + +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "navigateTo Failed: Invalid refID" +// ) + } + } , creationParams["clientID"] as String, creationParams["clientKey"] as String ) + + } catch (e: Exception) { + Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e) +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "Failed: Exception - ${e.message}" +// ) + } + } + + /** + * Called when Penguin UI setup is successful. + * + * @param warningCode Optional warning code received from the SDK. + */ + override fun onPenNavSuccess(warningCode: String?) { + val clinicId = creationParams["clinicID"] as String + + if(clinicId.isEmpty()) return + + navigateTo(clinicId) + } + + /** + * Called when there is an initialization error with Penguin UI. + * + * @param description Description of the error. + * @param errorType Type of initialization error. + */ + override fun onPenNavInitializationError( + description: String?, + errorType: InitializationErrorType? + ) { + val arguments: Map = mapOf( + "description" to description, + "type" to errorType?.name + ) + + channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments) + Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show() + } + + /** + * Called when Penguin UI is dismissed. + */ + override fun onPenNavUIDismiss() { + // Handle UI dismissal if needed + try { + mContext.unregisterReceiver(permissionResultReceiver) + dispose(); + } catch (e: IllegalArgumentException) { + Log.e("PenguinView", "Receiver not registered: $e") + } + } +} + 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 7fbf859a..57da2eb8 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 @@ -22,7 +22,7 @@ import com.github.kittinunf.fuel.httpPost import com.google.gson.Gson import com.google.gson.reflect.TypeToken import io.flutter.plugin.common.MethodChannel -import org.jetbrains.anko.doAsyncResult +//import org.jetbrains.anko.doAsyncResult import org.json.JSONArray import org.json.JSONException import org.json.JSONObject @@ -149,7 +149,7 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) - .setSmallIcon(R.mipmap.ic_launcher) + .setSmallIcon(R.mipmap.ic_launcher_local) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) .setContentTitle(title) @@ -208,7 +208,6 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP .header("Content-Type", "application/json") .header("Allow", "*/*") .response { request, response, result -> - result.doAsyncResult { } result.fold({ data -> val dataString = String(data) if (isJSONValid(dataString)) { diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png similarity index 100% rename from android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png similarity index 100% rename from android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png similarity index 100% rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png similarity index 100% rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png similarity index 100% rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 4e107030..1093435a 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -19,4 +19,5 @@ Geofence requests happened too frequently. + sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg diff --git a/android/build.gradle b/android/build.gradle index b5185cca..cc067af7 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -12,7 +12,23 @@ buildscript { repositories { google() jcenter() + mavenCentral() maven { url 'https://developer.huawei.com/repo/' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + + credentials { + username = 'mapbox' +// password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" + password = "pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ" + if (password == null || password == "") { + throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.") + } + } + authentication { + basic(BasicAuthentication) + } + } // maven { // url "https://dl.bintray.com/kotlin/kotlin-eap/" @@ -26,6 +42,7 @@ buildscript { // classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' classpath 'com.huawei.agconnect:agcp:1.5.2.300' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12' + classpath "com.mapbox.gradle.plugins:access-token:0.4.0" } } @@ -34,12 +51,29 @@ allprojects { google() // jcenter() mavenCentral() + flatDir { + dirs 'libs' + } maven { url 'https://developer.huawei.com/repo/' } maven { url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + + credentials { + username = 'mapbox' + password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" + if (password == null || password == "") { + throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.") + } + } + authentication { + basic(BasicAuthentication) + } + } } } diff --git a/android/google-services.json b/android/google-services.json index dd4038cf..3707617c 100644 --- a/android/google-services.json +++ b/android/google-services.json @@ -21,19 +21,24 @@ ], "api_key": [ { - "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg" } ], "services": { - "analytics_service": { - "status": 1 - }, "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 + "other_platform_oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } + } + ] } } } diff --git a/android/gradle.properties b/android/gradle.properties index 06a44c05..cb9913a1 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -3,3 +3,6 @@ org.gradle.jvmargs=-Xmx4096m android.useAndroidX=true android.enableJetifier=true android.suppressUnsupportedCompileSdk=33 +MAPBOX_USER_NAME = "mapbox" +#MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" +MAPBOX_DOWNLOADS_TOKEN="pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ" \ No newline at end of file diff --git a/assets/images/new/NFCCheckIn_QR_gps_HMG.png b/assets/images/new/NFCCheckIn_QR_gps_HMG.png new file mode 100644 index 00000000..20fc0ef6 Binary files /dev/null and b/assets/images/new/NFCCheckIn_QR_gps_HMG.png differ diff --git a/assets/images/progress-loading-red-crop-1.gif b/assets/images/progress-loading-red-crop-1.gif new file mode 100644 index 00000000..6dba7901 Binary files /dev/null and b/assets/images/progress-loading-red-crop-1.gif differ diff --git a/google-services_HMG.json b/google-services_HMG.json index dd4038cf..5806fa5f 100644 --- a/google-services_HMG.json +++ b/google-services_HMG.json @@ -25,15 +25,20 @@ } ], "services": { - "analytics_service": { - "status": 1 - }, "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 + "other_platform_oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } + } + ] } } } diff --git a/google-services_HMG_old.json b/google-services_HMG_old.json new file mode 100644 index 00000000..dd4038cf --- /dev/null +++ b/google-services_HMG_old.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "android_client_info": { + "package_name": "com.ejada.hmg" + } + }, + "oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/google-services_old.json b/google-services_old.json new file mode 100644 index 00000000..5806fa5f --- /dev/null +++ b/google-services_old.json @@ -0,0 +1,47 @@ +{ + "project_info": { + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "android_client_info": { + "package_name": "com.ejada.hmg" + } + }, + "oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index cb6be309..c5ff5d37 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 13.0 diff --git a/ios/Podfile b/ios/Podfile index 5495f0ca..7721bb87 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,9 +1,9 @@ # Uncomment this line to define a global platform for your project -platform :ios, '13.0' +platform :ios, '14.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' - +# use_frameworks! :linkage => :static project 'Runner', { 'Debug' => :debug, 'Profile' => :release, @@ -33,6 +33,8 @@ target 'Runner' do pod 'OpenTok', '~> 2.22.0' pod 'VTO2Lib' + pod 'MapboxMaps', '10.18.2' + pod 'FLAnimatedImage' flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end @@ -54,6 +56,7 @@ post_install do |installer| ] build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' xcconfig_path = build_configuration.base_configuration_reference.real_path xcconfig = File.read(xcconfig_path) xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR") @@ -62,6 +65,17 @@ post_install do |installer| if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle' build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF' end + if target.name == 'MapboxMobileEvents' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents -o Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents` + end + + if target.name == 'MapboxCommon' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon -o Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon` + end + + if target.name == 'MapboxCoreMaps' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps -o Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps` + end end end end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 130bc8cc..2c0073ff 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,17 +8,28 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */; }; 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; }; 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; }; 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */; }; + 47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; }; + 47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; }; + 47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; }; + 47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; }; 762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; }; 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; }; 76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; }; + 76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */; }; + 76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B692C6B819000DAFB84 /* PenguinModel.swift */; }; + 76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */; }; + 76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */; }; + 76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */; }; 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -40,15 +51,19 @@ 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 */; }; + FD7241B0D73FB24C87572FAC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E413842321D0D624872E9BE /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + 768D81742C6DF6E4005C655F /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( + 47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */, + 47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */, + 47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -58,12 +73,15 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; }; 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = ""; }; 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = ""; }; 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; }; 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = ""; }; + 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = ""; }; + 47C934FC2C91766400981BA7 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = ""; }; 6EE8819867EC2775AB578377 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -74,9 +92,15 @@ 7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = ""; }; 76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; }; + 76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; }; + 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = ""; }; + 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = ""; }; + 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = ""; }; 76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 838788A2BEDC4910F4B029A6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 8E413842321D0D624872E9BE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -113,7 +137,10 @@ 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */, 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */, E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */, - 4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */, + 47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */, + 47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */, + 47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */, + FD7241B0D73FB24C87572FAC /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -133,10 +160,13 @@ 555EAAA626EFB641859EF0BE /* Frameworks */ = { isa = PBXGroup; children = ( + 47C934FC2C91766400981BA7 /* Penguin.xcframework */, + 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */, + 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */, 76F2556027F1FFED0062C1CD /* PassKit.framework */, 76815B26275F381C00E66E94 /* HealthKit.framework */, E9620804255C2ED100D3A35D /* NetworkExtension.framework */, - 3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */, + 8E413842321D0D624872E9BE /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -151,6 +181,18 @@ path = Pods; sourceTree = ""; }; + 76D71B682C6B817500DAFB84 /* Penguin */ = { + isa = PBXGroup; + children = ( + 76D71B692C6B819000DAFB84 /* PenguinModel.swift */, + 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */, + 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */, + 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */, + 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */, + ); + path = Penguin; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -186,6 +228,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 76D71B682C6B817500DAFB84 /* Penguin */, 762D738C274E42650063CE73 /* ring_30Sec.caf */, 762D738D274E42650063CE73 /* ring_30Sec.mp3 */, 306FE6C9271D8B54002D6EFC /* OpenTok */, @@ -220,6 +263,7 @@ E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */, E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, + 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */, ); path = Helper; sourceTree = ""; @@ -254,7 +298,7 @@ 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, + 768D81742C6DF6E4005C655F /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */, 4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */, @@ -274,7 +318,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -419,12 +463,18 @@ buildActionMask = 2147483647; files = ( 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */, + 76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */, E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, + 76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */, E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + 76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */, + 29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */, + 76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */, + 76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */, 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, @@ -528,6 +578,7 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; @@ -549,14 +600,17 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.5.93; + MARKETING_VERSION = 4.5.991; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_COMPILATION_MODE = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -675,6 +729,7 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; @@ -696,14 +751,18 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.5.93; + MARKETING_VERSION = 4.5.991; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_COMPILATION_MODE = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -713,6 +772,7 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; @@ -734,15 +794,18 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.5.93; + MARKETING_VERSION = 4.5.991; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_COMPILATION_MODE = singlefile; "SWIFT_COMPILATION_MODE[arch=*]" = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fab8f735..b2d2f7e5 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ HMGPenguinInPlatformBridge{ + assert((HMGPenguinInPlatformBridge.shared_ != nil), "HMGPenguinInPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.") + return HMGPenguinInPlatformBridge.shared_! + } + + private func openChannel(){ + flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: mainViewController.binaryMessenger) + + flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in + print("Called function \(methodCall.method)") + + if let arguments = methodCall.arguments as Any? { + if methodCall.method == "launchPenguin"{ + print("====== launchPenguinView Launched =========") + self.launchPenguinView(arguments: arguments, result: result) + } + } else { + result(FlutterError(code: "INVALID_ARGUMENT", message: "Storyboard name is required", details: nil)) + } + } + } + + private func launchPenguinView(arguments: Any, result: @escaping FlutterResult) { + + let penguinView = PenguinView( + frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height), + viewIdentifier: 0, + arguments: arguments, + binaryMessenger: mainViewController.binaryMessenger + ) + + let penguinUIView = penguinView.view() + penguinUIView.frame = mainViewController.view.bounds + penguinUIView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + mainViewController.view.addSubview(penguinUIView) + + guard let args = arguments as? [String: Any], + let loaderImageData = args["loaderImage"] as? FlutterStandardTypedData else { + print("loaderImage data not found in arguments") + result(FlutterError(code: "ARGUMENT_ERROR", message: "Missing loaderImage data", details: nil)) + return + } + + let loadingOverlay = UIView(frame: UIScreen.main.bounds) + loadingOverlay.backgroundColor = UIColor.black.withAlphaComponent(0.5) // Semi-transparent overlay + loadingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + // Display the GIF using FLAnimatedImage + let animatedImage = FLAnimatedImage(animatedGIFData: loaderImageData.data) + let gifImageView = FLAnimatedImageView() + gifImageView.animatedImage = animatedImage + gifImageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + gifImageView.center = loadingOverlay.center + gifImageView.contentMode = .scaleAspectFit + loadingOverlay.addSubview(gifImageView) + + + if let window = UIApplication.shared.windows.first { + window.addSubview(loadingOverlay) + + } else { + print("Error: Main window not found") + } + + penguinView.onSuccess = { + // Hide and remove the loader + DispatchQueue.main.async { + loadingOverlay.removeFromSuperview() + + } + } + + result(nil) + } +} diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 43474d39..a67c0647 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -39,7 +39,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 11.0 + 13.0 NFCReaderUsageDescription This app requires NFC Usage access to allow for Online CheckIn for appointments. NSAppTransportSecurity @@ -60,7 +60,7 @@ NSCalendarsUsageDescription This app requires calendar access to set reminders for Virtual & Normal Appointments. NSCalendarsWriteOnlyAccessUsageDescription - This app requires calendar access to set reminders for Virtual & Normal Appointments. + This app requires calendar access to set reminders for Virtual & Normal Appointments. NSCalendarsFullAccessUsageDescription This app requires calendar access to set reminders for Virtual & Normal Appointments. NSCameraUsageDescription @@ -120,5 +120,7 @@ UIApplicationSupportsIndirectInputEvents + MBXAccessToken + pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ diff --git a/ios/Runner/Penguin/PenguinModel.swift b/ios/Runner/Penguin/PenguinModel.swift new file mode 100644 index 00000000..e41979d6 --- /dev/null +++ b/ios/Runner/Penguin/PenguinModel.swift @@ -0,0 +1,76 @@ +// +// PenguinModel.swift +// Runner +// +// Created by Amir on 06/08/2024. +// + +import Foundation + +// Define the model class +struct PenguinModel { + let baseURL: String + let dataURL: String + let dataServiceName: String + let positionURL: String + let clientKey: String + let storyboardName: String + let mapBoxKey: String + let clientID: String + let positionServiceName: String + let username: String + let isSimulationModeEnabled: Bool + let isShowUserName: Bool + let isUpdateUserLocationSmoothly: Bool + let isEnableReportIssue: Bool + let languageCode: String + let clinicID: String + let patientID: String + let projectID: String + + // Initialize the model from a dictionary + init?(from dictionary: [String: Any]) { + guard + let baseURL = dictionary["baseURL"] as? String, + let dataURL = dictionary["dataURL"] as? String, + let dataServiceName = dictionary["dataServiceName"] as? String, + let positionURL = dictionary["positionURL"] as? String, + let clientKey = dictionary["clientKey"] as? String, + let storyboardName = dictionary["storyboardName"] as? String, + let mapBoxKey = dictionary["mapBoxKey"] as? String, + let clientID = dictionary["clientID"] as? String, + let positionServiceName = dictionary["positionServiceName"] as? String, + let username = dictionary["username"] as? String, + let isSimulationModeEnabled = dictionary["isSimulationModeEnabled"] as? Bool, + let isShowUserName = dictionary["isShowUserName"] as? Bool, + let isUpdateUserLocationSmoothly = dictionary["isUpdateUserLocationSmoothly"] as? Bool, + let isEnableReportIssue = dictionary["isEnableReportIssue"] as? Bool, + let languageCode = dictionary["languageCode"] as? String, + let clinicID = dictionary["clinicID"] as? String, + let patientID = dictionary["patientID"] as? String, + let projectID = dictionary["projectID"] as? String + else { + print("Initialization failed due to missing or invalid keys.") + return nil + } + + self.baseURL = baseURL + self.dataURL = dataURL + self.dataServiceName = dataServiceName + self.positionURL = positionURL + self.clientKey = clientKey + self.storyboardName = storyboardName + self.mapBoxKey = mapBoxKey + self.clientID = clientID + self.positionServiceName = positionServiceName + self.username = username + self.isSimulationModeEnabled = isSimulationModeEnabled + self.isShowUserName = isShowUserName + self.isUpdateUserLocationSmoothly = isUpdateUserLocationSmoothly + self.isEnableReportIssue = isEnableReportIssue + self.languageCode = languageCode + self.clinicID = clinicID + self.patientID = patientID + self.projectID = projectID + } +} diff --git a/ios/Runner/Penguin/PenguinNavigator.swift b/ios/Runner/Penguin/PenguinNavigator.swift new file mode 100644 index 00000000..e7ce55b4 --- /dev/null +++ b/ios/Runner/Penguin/PenguinNavigator.swift @@ -0,0 +1,57 @@ +import PenNavUI +import UIKit + +class PenguinNavigator { + private var config: PenguinModel + + init(config: PenguinModel) { + self.config = config + } + + private func logError(_ message: String) { + // Centralized logging function + print("PenguinSDKNavigator Error: \(message)") + } + + func navigateToPOI( referenceId:String,completion: @escaping (Bool, String?) -> Void) { + PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in + + if let error = error { + let errorMessage = "Token error while getting the for Navigate to method" + completion(false, "Failed to get token: \(errorMessage)") + + print("Failed to get token: \(errorMessage)") + return + } + + guard let token = token else { + completion(false, "Token is nil") + print("Token is nil") + return + } + print("Token Generated") + print(token); + + + } + } + + private func handleNavigation(referenceId: String, token: String, completion: @escaping (Bool, String?) -> Void) { + DispatchQueue.main.async { + PenNavUIManager.shared.setToken(token: token) + + PenNavUIManager.shared.navigate(to: referenceId) { [weak self] _, navError in + guard let self = self else { return } + + if let navError = navError { + self.logError("Navigation error: Reference ID invalid") + completion(false, "Navigation error: \(navError.localizedDescription)") + return + } + + // Navigation successful + completion(true, nil) + } + } + } +} diff --git a/ios/Runner/Penguin/PenguinPlugin.swift b/ios/Runner/Penguin/PenguinPlugin.swift new file mode 100644 index 00000000..029bec35 --- /dev/null +++ b/ios/Runner/Penguin/PenguinPlugin.swift @@ -0,0 +1,31 @@ +// +// BlueGpsPlugin.swift +// Runner +// +// Created by Penguin . +// + +//import Foundation +//import Flutter +// +///** +// * A Flutter plugin for integrating Penguin SDK functionality. +// * This class registers a view factory with the Flutter engine to create native views. +// */ +//class PenguinPlugin: NSObject, FlutterPlugin { +// +// /** +// * Registers the plugin with the Flutter engine. +// * +// * @param registrar The [FlutterPluginRegistrar] used to register the plugin. +// * This method is called when the plugin is initialized, and it sets up the communication +// * between Flutter and native code. +// */ +// public static func register(with registrar: FlutterPluginRegistrar) { +// // Create an instance of PenguinViewFactory with the binary messenger from the registrar +// let factory = PenguinViewFactory(messenger: registrar.messenger()) +// +// // Register the view factory with a unique ID for use in Flutter code +// registrar.register(factory, withId: "penguin_native") +// } +//} diff --git a/ios/Runner/Penguin/PenguinView.swift b/ios/Runner/Penguin/PenguinView.swift new file mode 100644 index 00000000..b5161eb0 --- /dev/null +++ b/ios/Runner/Penguin/PenguinView.swift @@ -0,0 +1,445 @@ +// + +// BlueGpsView.swift + +// Runner + +// + +// Created by Penguin. + +// + + + +import Foundation +import UIKit +import Flutter +import PenNavUI + +import Foundation +import Flutter +import UIKit + + + +/** + + * A custom Flutter platform view for displaying Penguin UI components. + + * This class integrates with the Penguin navigation SDK and handles UI events. + + */ + +class PenguinView: NSObject, FlutterPlatformView, PIEventsDelegate, PenNavInitializationDelegate + +{ + // The main view displayed within the platform view + + private var _view: UIView + + private var model: PenguinModel? + + private var methodChannel: FlutterMethodChannel + + var onSuccess: (() -> Void)? + + + + + + + + /** + + * Initializes the PenguinView with the provided parameters. + + * + + * @param frame The frame of the view, specifying its size and position. + + * @param viewId A unique identifier for this view instance. + + * @param args Optional arguments provided for creating the view. + + * @param messenger The [FlutterBinaryMessenger] used for communication with Dart. + + */ + + init( + + frame: CGRect, + + viewIdentifier viewId: Int64, + + arguments args: Any?, + + binaryMessenger messenger: FlutterBinaryMessenger? + + ) { + + _view = UIView() + + methodChannel = FlutterMethodChannel(name: "launch_penguin_ui", binaryMessenger: messenger!) + + + + super.init() + + + + // Get the screen's width and height to set the view's frame + + let screenWidth = UIScreen.main.bounds.width + + let screenHeight = UIScreen.main.bounds.height + + + + // Uncomment to set the background color of the view + + // _view.backgroundColor = UIColor.red + + + + // Set the frame of the view to cover the entire screen + + _view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight) + + print("========Inside Penguin View ========") + + print(args) + + guard let arguments = args as? [String: Any] else { + + print("Error: Arguments are not in the expected format.") + + return + + } + + print("===== i got tha Args=======") + + + + // Initialize the model from the arguments + + if let penguinModel = PenguinModel(from: arguments) { + + self.model = penguinModel + + initPenguin(args: penguinModel) + + } else { + + print("Error: Failed to initialize PenguinModel from arguments ") + + } + + // Initialize the Penguin SDK with required configurations + + // initPenguin( arguments: args) + + } + + + + /** + + * Initializes the Penguin SDK with custom configuration settings. + + */ + + func initPenguin(args: PenguinModel) { + +// Set the initialization delegate to handle SDK initialization events + + PenNavUIManager.shared.initializationDelegate = self + + // Configure the Penguin SDK with necessary parameters + + PenNavUIManager.shared + + .setClientKey(args.clientKey) + + .setClientID(args.clientID) + + .setUsername(args.username) + + .setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled) + + .setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL) + + .setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName) + + .setIsShowUserName(args.isShowUserName) + + .setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly) + + .setEnableReportIssue(enable: args.isEnableReportIssue) + + .setLanguage(args.languageCode) + + .setBackButtonVisibility(true) + + .build() + + } + + + + + + /** + + * Returns the main view associated with this platform view. + + * + + * @return The UIView instance that represents this platform view. + + */ + + func view() -> UIView { + + return _view + + } + + + + // MARK: - PIEventsDelegate Methods + + + + + + + + + + /** + + * Called when the Penguin UI is dismissed. + + */ + + func onPenNavUIDismiss() { + + // Handle UI dismissal if needed + + print("====== onPenNavUIDismiss =========") + + + + + + self.view().removeFromSuperview() + + } + + + + /** + + * Called when a report issue is generated. + + * + + * @param issue The type of issue reported. + + */ + + func onReportIssue(_ issue: PenNavUI.IssueType) { + + // Handle report issue events if needed + + print("====== onReportIssueError =========") + + methodChannel.invokeMethod("onReportIssue", arguments: ["issueType": issue]) + + + + } + + + + /** + + * Called when the Penguin UI setup is successful. + + */ + + func onPenNavSuccess() { + + print("====== onPenNavSuccess =========") + + onSuccess?() + + methodChannel.invokeMethod("onPenNavSuccess", arguments: nil) + + // Obtain the FlutterViewController instance + + let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController + + + + print("====== after controller onPenNavSuccess =========") + + + + // Set the events delegate to handle SDK events + + PenNavUIManager.shared.eventsDelegate = self + + + + print("====== after eventsDelegate onPenNavSuccess =========") + + + + // Present the Penguin UI on top of the Flutter view controller + + PenNavUIManager.shared.present(root: controller, view: _view) + + + + + + print("====== after present onPenNavSuccess =========") + + print(model?.clinicID) + + print("====== after present onPenNavSuccess =========") + + + + guard let config = self.model else { + + print("Error: Config Model is nil") + + return + + } + + + + guard let clinicID = self.model?.clinicID, + + let clientID = self.model?.clientID, !clientID.isEmpty else { + + print("Error: Config Client ID is nil or empty") + + return + + } + + + + let navigator = PenguinNavigator(config: config) + + + + PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in + + if let error = error { + + let errorMessage = "Token error while getting the for Navigate to method" + + print("Failed to get token: \(errorMessage)") + + return + + } + + + + guard let token = token else { + + print("Token is nil") + + return + + } + + print("Token Generated") + + print(token); + + + + self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in + + if success { + + print("Navigation successful") + + } else { + + print("Navigation failed: \(errorMessage ?? "Unknown error")") + + } + + + + } + + + + print("====== after Token onPenNavSuccess =========") + + } + + + + } + + + + + + + + private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) { + + DispatchQueue.main.async { + + PenNavUIManager.shared.setToken(token: token) + + PenNavUIManager.shared.navigate(to: clinicID) + + completion(true,nil) + + } + + } + + + + + + + + + + /** + + * Called when there is an initialization error with the Penguin UI. + + * + + * @param errorType The type of initialization error. + + * @param errorDescription A description of the error. + + */ + + func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) { + + // Handle initialization errors if needed + + print("onPenNavInitializationErrorType: \(errorType.rawValue)") + + print("onPenNavInitializationError: \(errorDescription)") + } +} diff --git a/ios/Runner/Penguin/PenguinViewFactory.swift b/ios/Runner/Penguin/PenguinViewFactory.swift new file mode 100644 index 00000000..a88bb5d0 --- /dev/null +++ b/ios/Runner/Penguin/PenguinViewFactory.swift @@ -0,0 +1,59 @@ +// +// BlueGpsViewFactory.swift +// Runner +// +// Created by Penguin . +// + +import Foundation +import Flutter + +/** + * A factory class for creating instances of [PenguinView]. + * This class implements `FlutterPlatformViewFactory` to create and manage native views. + */ +class PenguinViewFactory: NSObject, FlutterPlatformViewFactory { + + // The binary messenger used for communication with the Flutter engine + private var messenger: FlutterBinaryMessenger + + /** + * Initializes the PenguinViewFactory with the given messenger. + * + * @param messenger The [FlutterBinaryMessenger] used to communicate with Dart code. + */ + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + /** + * Creates a new instance of [PenguinView]. + * + * @param frame The frame of the view, specifying its size and position. + * @param viewId A unique identifier for this view instance. + * @param args Optional arguments provided for creating the view. + * @return An instance of [PenguinView] configured with the provided parameters. + */ + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return PenguinView( + frame: frame, + viewIdentifier: viewId, + arguments: args, + binaryMessenger: messenger) + } + + /** + * Returns the codec used for encoding and decoding method channel arguments. + * This method is required when `arguments` in `create` is not `nil`. + * + * @return A [FlutterMessageCodec] instance used for serialization. + */ + public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { + return FlutterStandardMessageCodec.sharedInstance() + } +} diff --git a/lib/config/config.dart b/lib/config/config.dart index 2e0b100b..e69f0510 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -20,11 +20,12 @@ var PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; var PACKAGES_ORDERS = '/api/orders'; var PACKAGES_ORDER_HISTORY = '/api/orders/items'; var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; -// var BASE_URL = 'http://10.50.100.198:1022/'; -// var BASE_URL = 'http://10.50.100.198:4422/'; -// var BASE_URL = 'https://uat.hmgwebservices.com/'; -var BASE_URL = 'https://hmgwebservices.com/'; -// var BASE_URL = 'http://10.20.200.111:1010/'; +// var BASE_URL = 'http://10.50.100.198:2018/'; +// var BASE_URL = 'http://10.50.100.198:4422/'; +var BASE_URL = 'https://uat.hmgwebservices.com/'; +// var BASE_URL = 'https://hmgwebservices.com/'; +// var BASE_URL = 'http://10.20.200.111:1010/'; +// var BASE_URL = 'https://hmgwebservices.com/'; // var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidamergeuat.cloudsolutions.com.sa/'; @@ -215,6 +216,7 @@ var GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID'; //URL to get clinic list var GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; +var GET_CLINICS_LIST_WRT_HOSPITAL_URL = "Services/Lists.svc/REST/GetClinicFromDoctorSchedule"; //URL to get active appointment list var GET_ACTIVE_APPOINTMENTS_LIST_URL = "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; @@ -313,6 +315,8 @@ var GET_LIVECARE_CLINIC_TIMING = 'Services/ER_VirtualCall.svc/REST/PatientER_Get var GET_ER_APPOINTMENT_FEES = 'Services/DoctorApplication.svc/REST/GetERAppointmentFees'; var GET_ER_APPOINTMENT_TIME = 'Services/ER_VirtualCall.svc/REST/GetRestTime'; +var CHECK_PATIENT_DERMA_PACKAGE = 'Services/OUTPs.svc/REST/getPatientPackageComponentsForOnlineCheckIn'; + var ADD_NEW_CALL_FOR_PATIENT_ER = 'Services/DoctorApplication.svc/REST/NewCallForPatientER'; var GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; @@ -333,18 +337,25 @@ var GET_PATIENT_HEALTH_STATS = 'Services/Patients.svc/REST/Med_GetTransactionsSt var SEND_CHECK_IN_NFC_REQUEST = 'Services/Patients.svc/REST/Patient_CheckAppointmentValidation_ForNFC'; +var CHECK_SCANNED_NFC_QR_CODE = 'Services/Patients.svc/REST/Patient_ValidationMachine_ForNFC'; + var HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation'; var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory'; var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert'; + var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update'; +var GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForWalkIn'; + +var CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/CanPayForWalkinAppointment'; + //URL to get medicine and pharmacies list var CHANNEL = 3; var GENERAL_ID = 'Cs2020@2016\$2958'; var IP_ADDRESS = '10.20.10.20'; -var VERSION_ID = 15.9; +var VERSION_ID = 16.9; var SETUP_ID = '91877'; var LANGUAGE = 2; // var PATIENT_OUT_SA = 0; @@ -601,9 +612,9 @@ var GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceFor var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental"; -var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamara/Home/GetInstallments'; +var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamaralive/Home/GetInstallments'; -var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamara/api/OnlineTamara/order_status?orderid='; +var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid='; var UPDATE_TAMARA_STATUS = 'Services/PayFort_Serv.svc/REST/Tamara_UpdateRequestStatus'; @@ -647,6 +658,8 @@ var GET_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/getBirthNotification_bymoth var SAVE_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/SaveBirthNotification'; +var INSERT_GENERAL_ADMISSION_CONSENT = 'Services/INPs.svc/REST/Inp_insertAAForGeneralAdmissionConsent'; + //Meal Plan APIs var GET_ADMITTED_PATIENTS = 'Services/MOP.svc/REST/GetAdmittedPatients'; var GET_CURRENT_WEEKID_WEEKDAY = 'Services/MOP.svc/REST/GetCurrentWeekAndDayHMGMP'; @@ -665,23 +678,30 @@ var GET_WE_CARE_TOUR_URL = 'Services/Consent.svc/Rest/Consent_VirtualJurny_Url_G var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification'; +var INSERT_WALKIN_APPOINTMENT = "Services/Doctors.svc/REST/InsertWalkinAppointment"; + +//Usage Agreement APIs +var CHECK_USAGE_AGREEMENT = "Services/Patients.svc/REST/CheckForUsageAgreement"; +var GET_USAGE_AGREEMENT = "Services/Patients.svc/REST/GetUsageAgreementText"; +var ADD_USAGE_AGREEMENT = "Services/Patients.svc/REST/AddUsageAgreement"; + var GET_ER_ONLINE_PAYMENT_DETAILS = 'Services/OUTPs.svc/Rest/Outp_GetPatientPaymentInformationForERClinic'; var AUTO_GENERATE_INVOICE_ER = 'Services/OUTPs.svc/Rest/Outp_AutoGenerateInvoiceForER'; var CHECK_IF_PATIENT_ARRIVED_ER_ONLINE_CHECKIN = 'Services/OUTPs.svc/Rest/IsPatientArrived'; -var CHECK_PATIENT_ER_CLINIC_BALANCE_AMOUNT = 'Services/OUTPs.svc/Rest/getPatientAdvanceBalanceAmountByClinic'; +var CHECK_PATIENT_ER_ADVANCE_BALANCE = 'Services/OUTPs.svc/Rest/getPatientAdvanceBalanceAmountByClinic'; var GET_PROJECT_FROM_NFC = 'Services/OUTPs.svc/Rest/GetProjectByNFC'; //PAYFORT var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails"; var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse"; -var payFortEnvironment = FortEnvironment.production; -var applePayMerchantId = "merchant.com.hmgwebservices"; -// var payFortEnvironment = FortEnvironment.test; -// var applePayMerchantId = "merchant.com.hmgwebservices.uat"; +// var payFortEnvironment = FortEnvironment.production; +// var applePayMerchantId = "merchant.com.hmgwebservices"; +var payFortEnvironment = FortEnvironment.test; +var applePayMerchantId = "merchant.com.hmgwebservices.uat"; class AppGlobal { static var context; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 311cb419..5912d123 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -45,6 +45,8 @@ const Map localizedValues = { 'name': {'en': 'Name', 'ar': 'الإسم'}, 'doctor': {'en': 'Doctor', 'ar': 'الطبيب'}, 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, + 'hospitalName': {'en': 'Hospital Name', 'ar': 'اسم المستشفى'}, + 'NoClinicFound': {'en': 'No Clinic Found', 'ar': 'لم يتم العثور على عيادة'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, 'nearestAppo': {'en': 'Nearest Appointment', 'ar': 'أقرب موعد'}, 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, @@ -1870,8 +1872,14 @@ const Map localizedValues = { "insuranceClassName": {"en": "Insurance Class", "ar": "فئة التأمين"}, "insuranceRequestSubmit": {"en": "Your insurance update request has been submitted successfully.", "ar": "تم تقديم طلب تحديث التأمين الخاص بك بنجاح."}, "NFCNotSupported": {"en": "Your device does not support NFC. Please visit reception to Check-In", "ar": "جهازك لا يدعم NFC. يرجى زيارة مكتب الاستقبال لتسجيل الوصول"}, - "enter-workplace-name": {"en": "Please enter your workplace name:", "ar": "رجاء إدخال مكان العمل:"}, - "workplaceName": {"en": "Workplace name:", "ar": "مكان العمل:"}, + "enter-workplace-name": {"en": "Please enter your workplace details:", "ar": "الرجاء إدخال تفاصيل مكان عملك:"}, + + // "workplaceName": {"en": "Workplace name:", "ar": "مكان العمل:"}, + "workplaceName": {"en": "Workplace name English", "ar": "مكان العمل انجليزي:"}, + "workplaceNameAr": {"en": "Workplace name Arabic *", "ar": "مكان العمل عربي:"}, + "occupationNameEn": {"en": "Occupation name English", "ar": "مكان العمل انجليزي:"}, + "occupationNameAr": {"en": "Occupation name Arabic *", "ar": "مكان العمل عربي:"}, + "callLiveCareSupport": {"en": "Call LiveCare Support", "ar": "اتصل بدعم اللايف كير"}, "needApproval": { "en": "Your sick leave is under process in medical administration, you will be notified once approved.", @@ -1913,6 +1921,8 @@ const Map localizedValues = { "consent": {"en": "Consent", "ar": "التنويم"}, "generalInstructionsTitle": {"en": "General", "ar": "تعليمات"}, "generalInstructionsSubTitle": {"en": "Instructions", "ar": "التنويم العامة"}, + "generalConsentTitle": {"en": "General", "ar": "الموافقة"}, + "generalConsentSubTitle": {"en": "Consent", "ar": "العامة"}, "medicalInstructionsTitle": {"en": "Medical", "ar": "التعليمات الطبية"}, "medicalInstructionsSubTitle": {"en": "Instructions", "ar": "قبل التنويم"}, "mealPlanTitle": {"en": "Meal Plan", "ar": "خدمات"}, @@ -1943,12 +1953,25 @@ const Map localizedValues = { "generalInstructions": {"en": "General Instructions:", "ar": "تعليمات عامة:"}, "copyLink": {"en": "COPY LINK", "ar": "نسخ الوصلة:"}, "paymentLinkCopied": {"en": "Payment link copied to your clipboard!'", "ar": "تم نسخ رابط الدفع إلى الحافظة الخاصة بك!"}, - "copyLinkTxt": {"en": "Or you can copy the payment link from below & send it to someone who can pay on your behalf: ", "ar": "أو يمكنك نسخ رابط الدفع من الأسفل وإرساله إلى شخص يمكنه الدفع نيابة عنك:"}, - "proErrorMessage": {"en": "Dear patient, Our staff is currently out of office, please note that our working hours are from 7:00 AM to 10:00 PM, and we'd love to help you during that time, or you can call ", "ar": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>"}, + "copyLinkTxt": { + "en": "Or you can copy the payment link from below & send it to someone who can pay on your behalf: ", + "ar": "أو يمكنك نسخ رابط الدفع من الأسفل وإرساله إلى شخص يمكنه الدفع نيابة عنك:" + }, + "proErrorMessage": { + "en": + "Dear patient, Our staff is currently out of office, please note that our working hours are from 7:00 AM to 10:00 PM, and we'd love to help you during that time, or you can call ", + "ar": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>" + }, "admissionNo": {"en": "Admission No", "ar": "رقم القبول:"}, "admissionReqNo": {"en": "Admission Request No", "ar": "رقم طلب القبول:"}, "dischargeDate": {"en": "Discharge Date", "ar": "تاريخ التفريغ"}, "selectAdmissionText": {"en": "Please select one of the admissions from below to view medical reports:", "ar": "يرجى تحديد أحد حالات القبول من الأسفل لعرض التقارير الطبية:"}, + "onlyAdmitted": {"en": "This service is only available for admitted patients", "ar": "هذه الخدمة متاحة فقط للمرضى المقبولين"}, + "assistYou": {"en": "How we may assist you?", "ar": "كيف يمكننا مساعدتك؟"}, + "receive": {"en": "Receive", "ar": "تجهيز"}, + "PRO": {"en": "PRO", "ar": "علاقات المرضى"}, + "patientRelationOffice": {"en": "Patient Relation Office", "ar": "علاقات المرضى"}, + "roomNo": {"en": "Room No.", "ar": "رقم الغرفة"}, "invalidEligibility": { "en": "You cannot make online payment because you are not eligible to use the provided service.", "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة." @@ -1965,10 +1988,7 @@ const Map localizedValues = { "validInsurance": {"en": "Do you have a valid insurance?", "ar": "هل لديك تأمين صالح؟"}, "contactRRT": {"en": "Contact RRT", "ar": "تواصل مع فريق الاستجابة السريعة"}, "checkInViaLocation": {"en": "Check-In Via Location", "ar": "تسجيل الوصول عبر الموقع"}, - "locationCheckInError": { - "en": "Please make sure that you're within the hospital location to perform online check-in.", - "ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت." - }, + "locationCheckInError": {"en": "Please ensure you're within the hospital location to perform online check-in.", "ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت."}, "upcoming": {"en": "Upcoming", "ar": "المواعيد القادمة"}, "noUpcomingAppointment": {"en": "No upcoming appointments", "ar": "لا توجد مواعيد القادمة"}, "locationTimeoutError": {"en": "Unable to fetch your location, Please try again.", "ar": "غير قادر على جلب موقعك، يرجى المحاولة مرة أخرى."}, @@ -1976,4 +1996,125 @@ const Map localizedValues = { "selectHospitalBloodDonation": {"en": "Please select the hospital you want to book an appointment with: ", "ar": "يرجى اختيار المستشفى الذي تريد حجز موعد معه:"}, "wecare": {"en": "We Care", "ar": "نحن نهتم"}, "myinstructions": {"en": "My Instructions", "ar": "تعليماتي"}, + "existingPackage": {"en": "This patient has a package under this clinic,", "ar": "هذا المريض لديه حزمة تحت هذه العيادة،"}, + "continueOrbookNew": {"en": "do you want to continue with that package? or book new appointment?", "ar": "هل تريد الاستمرار في هذه الباقة؟ أو حجز موعد جديد؟"}, + "newAppointment": {"en": "New Appointment", "ar": "موعد جديد"}, + "proceedPackage": {"en": "Proceed with package", "ar": "المضي قدما في الحزمة"}, + + "clinicLocation": {"en": "Clinic Location", "ar": "موقع العيادة"}, + "waitingAppointment": {"en": "Waiting appointment", "ar": "انتظار الموعد"}, + "whatWaitingAppointment": {"en": "What is Waiting appointment?", "ar": "ما هو انتظار الموعد؟"}, + "waitingAppointmentText1": { + "en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building, and in case there is no available slot in the doctor’s schedule.", + "ar": "تتيح لك خاصية انتظار المواعيد حجز موعد أثناء تواجدك داخل مبنى المستشفى، وفي حالة عدم وجود وقت متاح في جدول الطبيب." + }, + "waitingAppointmentText2": {"en": "The appointment with the doctor is confirmed, but the time of entry is uncertain", "ar": "دخول الموعد مؤكد, التوقيت غير محدد."}, + "waitingAppointmentText3": { + "en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", + "ar": "ملحوظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائيًا" + }, + "waitingAppointmentVerificationMethod": {"en": "Please select verification method", "ar": "الرجاء تحديد طريقة التحقق"}, + "howToUseVerificationMethod": {"en": "How to use verification methods?", "ar": "كيفية استخدام طرق التحقق؟"}, + "addToWaitingList": {"en": "Add to waiting list", "ar": "اضافه الى قائمة الانتظار"}, + "searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"}, + "selectBranch": {"en": "Select Branch", "ar": "اختر الفرع"}, + "searchByBranch": {"en": "Search By Branch Name", "ar": "البحث عن طريق اسم الفرع"}, + "hospitalNavigationTitle": {"en": "Hospital", "ar": "الملاحة"}, + "hospitalNavigationSubtitle": {"en": "Navigation", "ar": "المستشفى"}, + "continueAgreeTerms": {"en": "By continuing, You agree to the above Terms and Conditions.", "ar": "من خلال المتابعة، فإنك توافق على الشروط والأحكام المذكورة أعلاه."}, + "agreeText": {"en": "Agree", "ar": "أوافق"}, + "ERCheckInSuccess": {"en": "Your ER Online Check-In has been successfully done.", "ar": "لقد تم تسجيل وصولك للطوارئ عبر الإنترنت بنجاح."}, + "generalConsent": {"en": "General Consent: ", "ar": "موافقة عامة:"}, + + "generalConsent1": { + "en": + "I authorize the Hospital and their staff to conduct any diagnostic examinations, test (including, but not limited to, HIV, HBsAg and any other as the clinician may deem fit), procedures and to provide any medications, treatments or therapy necessary to effectively assess and maintain my health, and to assess, diagnose and treat my illness or injuries. I understand that it is the responsibility of my health care providers to explain the patient's condition and thereby reasons for any particular diagnostic examination, test or procedure, the available treatment options, the common risks, anticipated benefits associated with these options, alternative courses of treatment and possible outcomes of non-treatment.", + "ar": + "أفوض المستشفى وموظفيه بإجراء أية فحوصات واختبارات وإجراءات تشخيصية (بما في ذلك مثالاً وليس حصراً فحوصات أمراض الكبد الوبائية أو نقص المناعة المكتسبة أو أي فحوصات أخرى يرى الطبيب المعالج (مناسبتها وتقديم أية أدوية أو علاج ضروري لتقييم . صحتي والمحافظة عليها بفاعلية والتقييم وتشخيص ومعالجة مرضي او الإصابات اللاحقة بي، وأدرك بأنه من مسؤولية مقدمي الرعاية الصحية بيان أسباب أي فحص أو إختبار أو إجراء تشخيصي محدد وخيارات العلاج المتوفرة والمخاطرة الشائعة والمنافع المتوقعة المرتبطة بهذه الخيارات والعلاج البديل والنتائج المحتملة لرفض العلاج." + }, + "hospitalRules": {"en": "HOSPITAL RULES: ", "ar": "أنظمة المستشفى: "}, + "generalConsent2": { + "en": + "Agree to be obliged to adhere to the Hospital rules, and to ensure compliance by all visitors. In the event of any severe violations of the rules, the hospital reserves the right to take the necessary measures according to the applicable Laws.", + "ar": + "أوافق على التقيد بقواعد وأنظمة المستشفى، وأضمن التزام جميع الزوار بذلك ، في حالة حدوث أي إنتهاكات جسيمة لقواعد وأنظمة المستشفى، يحتفظ المستشفى بالحق في إتخاذ جميع الاجراءات النظامية المكفولة." + }, + "communicationConsent": {"en": "COMMUNICATION VIA EMAIL, TEXT MESSAGES AND PHONE CALLS: ", "ar": "الاتصال عبر البريد الإلكتروني والرسائل النصية والمكالمات الهاتفية: "}, + "generalConsent3": { + "en": + "I understand that the contact number or Email that I have provided on registration will be used for communication by the Hospital. I hereby agree to be notified by the Hospital through SMS, Email, phone calls or any other method, for appointments notifications, special promotions, new features or products, current HMG's medical services, and of any services introduced by the Hospital or any third party in the future or any modifications made to the services offered by the Hospital. And these messages may be submitted as evidence where the Hospital has the right to use at any time whatsoever and as it sees fit. I understand the risks of communicating by email and text messages, in particular the privacy risks. I understand that the Hospital cannot guarantee the security and confidentiality of email or text communication. The Hospital will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.", + "ar": + "المستشفى أدرك بأن رقم الجوال الهاتف أو البريد الإلكتروني الذي قدمته في نموذج التسجيل سيستخدم كوسيلة اتصال بيني وبين | وأقر بموافقتي على قيام المستشفى بإخطاري عن طريق رسائل البريد أو الرسائل القصيرة أو البريد الإلكتروني أو المكالمات الهاتفية أو أي طريقة أخرى بالمواعيد والعروض الترويجية أو المميزات والمنتجات الخاصة بالمستشفى أو) خاصة بأي طرف خارجي) وبأي خدمات طبية تقدمها المجموعة أو قد يطرحها المستشفى في المستقبل أو أي تعديلات قد تطرأ على الخدمات المقدمة من قبل المستشفى. وتعتبر هذه الرسائل دليل إثبات يحق للمستشفى استخدامه في اي وقت يشاء. أفهم مخاطر التواصل عبر البريد الإلكتروني والرسائل النصية خاصة مخاطر الخصوصية وأدرك أن المستشفى لا يمكنه ضمان أمن وسرية البريد الإلكتروني أو الرسائل النصية ولن يكون المستشفى مسؤول عن الرسائل التي لم يتم استلامها أو تسليمها بسبب الفشل التقني أو الكشف عن المعلومات السرية ما لم يكن سببها سوء سلوك متعمد." + }, + "releaseConsent": {"en": "RELEASE OF PERSONAL AND MEDICAL INFORMATION: ", "ar": "الإفصاح عن المعلومات الشخصية والطبية: "}, + "generalConsent4": { + "en": + "On completion of this consent I hereby authorize the hospital to provide any information of whatever nature concerning my treatment, including but not limited to, current conditions/co-morbidities to my insurance carrier or third party payer, for the purpose of determining benefit entitlement and to process payment, therefore taking responsibility for the financial settlement of my medical bills.", + "ar": + "عند تعبئة هذا النموذج ، أصرح بموجبه للمستشفي بتقديم أية معلومات أياً كانت طبيعتها بخصوص حالتي الصحية وعلاجي لشركة التأمين أو لأي طرف آخر مسؤول عن الدفع لأغراض تحديد حق الاستفادة والقيام بالدفع وبالتالي تحمل المسؤولية عن التسوية المالية للفواتير الطبية الخاصة بي." + }, + "generalConsent5": { + "en": + "The Hospital is obliged by local and government regulations to submit certain patient information and I hereby give consent for the disclosure or use of my information as per statutory requirement. I also acknowledge that this consent is subject to the laws and jurisdiction of the country in which the Hospital is located.", + "ar": + " إن المستشفى ملزم بموجب الأنظمة المحلية وأنظمة الدولة بتقديم بعض المعلومات المتعلقة بالمريض وأوافق بموجبه على إفصاح أو استخدام المستشفى للمعلومات الخاصة بي حسبما هو مطلوب نظاماً، وأن هذا الإقرار خاضع للأنظمة والقوانين والاختصاص القضائي للدولة حيث يقع المستشفى." + }, + "valuables": {"en": "VALUABLES: ", "ar": "الممتلكات الثمينة: "}, + "generalConsent6": { + "en": "The Hospital is not liable for the loss or damage of any money, jewelry, documents or other personal articles of value.", + "ar": "المستشفى غير مسؤول عن ضياع أو تلف أي أموال أو مجوهرات أو مستندات أو أي أشياء أخري ذات قيمة." + }, + "financialConsent": {"en": "FINANCIAL AGREEMENT: ", "ar": "الموافقة المالية: "}, + "generalConsent7": { + "en": + "Within the expected time frame during their hospital visit or stay, patients/relatives are required to take personal responsibility and meet any financial obligation towards the Hospital regardless of the mode and source of payment (i.e. self-paying, insurance company, sponsoring company & others). I understand that for credit cases (Insurance covered or corporate patients) approval letter is essential at the time of admission. In case the approval letter is not available, I, the undersigned, agree to be treated as cash patient and advance deposit shall be made. Once approval is obtained the amount paid as advance shall be refunded to me / patient and if there is no approval till discharge the bill shall be settled in full by me/patient.", + "ar": + "يتوجب علي ضمن الاطار الزمني المتوقع أثناء زيارة المستشفى أو الإقامة فيها تحمل المسؤولية الشخصية والوفاء بأي التزام مالي تجاه المستشفى بغض النظر عن طريقة ومصدر الدفع (أي: الدفع الذاتي أو شركة التأمين أو صاحب العمل أو غيره، وأن الموافقة المسبقة ضرورية قبل دخول المستشفى في حالة التغطية المالية من قبل شركة التأمين أو شركة الكفالة في الحالات التي يتم فيها تأخر الموافقة أتعهد أنا الموقع أدناه بالموافقة على العلاج كمريض دفع ذاتي ويجب إيداع مبلغ تحت الحساب يتم استرداده بعد الحصول على موافقة التأمين، ويجب دفع الحساب بالكامل في حالة عدم الحصول على موافقة التأمين حتى موعد الخروج." + }, + "dataSharingConsent": {"en": "DATA SHARING AND INQUIRY: ", "ar": "تبادل المعلومات والاستفسارات: "}, + "generalConsent8": { + "en": + "Hereby, I, the undersigned, agree to provide the Hospital with any information that it requires for the establishing and/or auditing and/or administering my accounts and facilities therewith and I authorize it to obtain and collect any information as it deems necessary or in need for regarding me, my accounts and facilities therewith, from the Saudi Credit Bureau (SIMAH) or to any other agency approved by Saudi Arabian Monetary Agency (SAMA) and to disclose and share (inclusive of Data Pooling) that information to the said company (SIMAH) or to any other agency approved by Saudi Arabian Monetary Agency (SAMA) in accordance with the Membership Agreement and Code of Conduct approved. I agree and acknowledge that the delay in payment or non-payment of Hospital dues is a failure and as a result, SIMAH and/or any other agency approved by will be provided with my name and information to be added to the lists at SIMAH. These lists are accessed by other parties, and I will not be removed from these lists until I pay all of the outstanding amounts.", + "ar": + "بهذا أنا الموقع أدناه أوافق على تزويد المستشفى بأي معلومات أو بيانات يطلبها مني لتأسيس ملفي لدى المستشفى و/أو لمراجعته و/ أو لإدارته وأفوض المستشفى بأن يحصل على ما يلزم أو يحتاج إليه من معلومات تخصني من الشركة السعودية للمعلومات الائتمانية (سمة) واو اي جهة أخرى معتمدة من مؤسسة النقد العربي السعودي (ساما). كما أوافق على أن يفصح المستشفى عن المعلومات الخاصة بي لدى المستشفى للشركة السعودية للمعلومات الائتمانية (سمة) واو اي جهة أخرى معتمدة من مؤسسة النقد العربي السعودي (ساما) من خلال إتفاقية العضوية المبرمة وقواعد العمل المقرة والخاصة بتبادل المعلومات. كما أوافق وأقر بان التأخير في السداد أو عدم السداد لمستحقات المستشفى يعتبر تقصيراً وإخلالاً مني ونتيجة لذلك سيتم تزويد الشركة السعودية للمعلومات الائتمانية (سمه) و/أو أي جهة أخرى توافق عليها مؤسسة النقد العربي السعودي (ساما) بإسمي ومعلوماتي الإضافتها على القوائم لديها هذه القوائم يتم الوصول اليها والإطلاع عليها من قبل جهات أخرى، ولن يتم رفع اسمي من تلك القوائم إلا بعد أداء كافة ما علي من مبالغ مستحقة." + }, + "permissionLeaveConsent": {"en": "PERMISSION TO LEAVE THE HOSPITAL: ", "ar": "قواعد المستشفى: "}, + "generalConsent9": { + "en": + "Fully understand that, at no time, patient can leave the Hospital without prior consent and approval of treating doctor. In case I insist on leaving the Hospital, I must sign an undertaking of my responsibility on leaving the Hospital against the medical advice.", + "ar": "اتفهم انه ليس بإمكاني مغادرة المستشفى في أي وقت شئت دون أخذ إذن طبيبي المعالج. وفي حالة إصراري على مغادرة المستشفى يتعين علي توقيع اقرار مغادرتي ضد النصيحة الطبية وعلى مسؤوليتي." + }, + "observeConsent": {"en": "CONSENT TO OBSERVE: ", "ar": "قواعد المستشفى: "}, + "generalConsent10": { + "en": + "Observers will be allowed according to the Hospital policy as will the taking of pictures of medical or surgical procedures and the use of same for internal staff education or process improvement purposes. Observation and photography or medical or surgical procedures may be done with the approval of the Hospital and in accordance with the Hospital's policy and related laws. I, the undersigned, fully understand that electronically-transmitted information may be used and/or shared by the Hospital with other hospitals for my diagnosis, therapy, follow-up and/or patient education, and may include patient medical records, medical images, interactive audio, video, and/or data communications, output data from medical devices, sound and video files etc. for betterment of patient care.", + "ar": + "وفقاً لسياسة المستشفى، سيتم السماح للمراقبين بمتابعة الإجراءات الطبية والجراحية وسيتم استخدامها لتعليم الموظفين الداخليين أو لأغراض التحسين والتطوير ويمكن إجراء المراقبة والتصوير الفوتوغرافي أو الإجراءات الطبية أو الجراحية بموافقة المستشفى ووفقاً لسياسة المستشفى والانظمة ذات العلاقة. أنا الموقع ادناه أتفهم انه قد يتم الكترونياً إرسال معلومات متعلقة بالتشخيص الطبي لي، العلاج المتابعة وتثقيف المريض، والتي قد تتضمن ملف المريض الطبي النتائج الإشعاعية، التسجيلات الصوتية والمرئية، وذلك بين المستشفى ومستشفيات أخرى بهدف تقديم رعاية صحية أفضل." + }, + "noGuaranteeConsent": {"en": "NO GUARENTEE OF THE RESULTS OF TREATMENT OR EXAMINATION: ", "ar": "لا ضمان لنتائج العلاج أو الفحوصات: "}, + "generalConsent11": { + "en": "I fully understand that no guarantee can be made to me as to the results of treatment or examinations done in the hospital during my hospitalization.", + "ar": "أنا الموقع أدناه أتفهم أنه لا يمكن ضمان نتائج العلاج أو الفحوصات أو الإجراءات التي قد تجرى لي خلال فترة وجودي بالمستشفى." + }, + "disputeConsent": {"en": "GOVERNING LAWS AND DISPUTE RESOLUTION: ", "ar": "النظام الحاكم وحل النزاعات: "}, + "generalConsent12": { + "en": + "This General Consent and Conditions of Admissions is governed by and shall be construed in accordance with the laws of the Kingdom of Saudi Arabia. Any dispute which arises during the execution of it, in which the parties have failed to resolve amicably, will be referred to the concerned judicial authorities in the city of Riyadh, Kingdom of Saudi Arabia.", + "ar": + "تخضع وتفسر هذه الموافقة العامة وشروط القبول للأنظمة المعمول بها في المملكة العربية السعودية. كل خلاف ينشأ عن تنفيذها ولا يتوصل إلى تسويته بين الطرفين وديا يحال إلى الجهة القضائية المختصة بالفصل في النزاع في مدينة الرياض، المملكة العربية السعودية." + }, + "patientsRightsConsent": {"en": "ACKNOWLEDGEMENT OF NOTICE OF PATIENT RIGHTS AND RESPONSIBILITIES: ", "ar": "الإقرار بحقوق ومسؤوليات المرضى: "}, + "generalConsent13": { + "en": + "I, the undersigned, acknowledge that I have been provided with a copy of the Patients' Bill of Right and Responsibilities and the admission staff has explained to me Patients' Bill of Right and Responsibilities.", + "ar": "أنا الموقع أدناه أقر بانه تم تزويدي بـ وثيقة حقوق ومسؤوليات المرضى وقام الموظف المختص بشرح وثيقة حقوق ومسؤوليات المرضى لي." + }, + "acknowledgementConsent": {"en": "ACKNOWLEDGEMENTS: ", "ar": "الإقرارات: "}, + "generalConsent14": { + "en": + "I, the undersigned, acknowledge that I have been provided with a copy of the Patients' Bill of Right and Responsibilities and the admission staff has explained to me Patients' Bill of Right and Responsibilities.", + "ar": + "لقد قرأت وفهمت وأوافق على الشروط والأحكام المبينة أعلاه وأوافق على الإلتزام بالمتطلبات المذكورة تجاه المستشفى ، لقد قرأت التفاصيل المبينة في نموذج التسجيل الخاص بي وأقر بأنها صحيحة. أنا الموقع ادناه أقر بأنه أتيحت لي الفرصة لطرح الأسئلة والتحفظات بشأن هذه الموافقة، وتلقيت إجابات مرضية على جميع إستفساراتي." + }, + "incorrectNationalId": {"en": "Incorrect National ID", "ar": "رقم الهوية غير صحيحة"}, }; diff --git a/lib/core/model/prescriptions/request_send_prescription_email.dart b/lib/core/model/prescriptions/request_send_prescription_email.dart index aff0e792..de162296 100644 --- a/lib/core/model/prescriptions/request_send_prescription_email.dart +++ b/lib/core/model/prescriptions/request_send_prescription_email.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_inp.dart'; class RequestSendPrescriptionEmail { String? appointmentDate; @@ -26,6 +27,7 @@ class RequestSendPrescriptionEmail { int? doctorID; int? projectID; List? listPrescriptions; + List? listPrescriptionsINP; RequestSendPrescriptionEmail( {this.appointmentDate, @@ -102,9 +104,12 @@ class RequestSendPrescriptionEmail { data['PatientMobileNumber'] = this.patientMobileNumber; data['PatientName'] = this.patientName; data['SetupID'] = this.setupID; - if (this.listPrescriptions != null) { + if (this.listPrescriptions != null && this.listPrescriptions!.isNotEmpty) { data['ListPrescriptions'] = this.listPrescriptions!.map((v) => v.toJson()).toList(); } + if (this.listPrescriptionsINP != null && this.listPrescriptionsINP!.isNotEmpty) { + data['ListPrescriptions'] = this.listPrescriptionsINP!.map((v) => v.toJson()).toList(); + } data['ClinicName'] = this.clinicName; data['DoctorName'] = this.doctorName; data['ProjectID'] = this.projectID; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index d8f30f0c..0ec508a0 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -31,8 +31,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); /// onFailure: (String error, int statusCode) {}, /// body: Map(); /// -AuthenticatedUserObject authenticatedUserObject = - locator(); +AuthenticatedUserObject authenticatedUserObject = locator(); VitalSignService _vitalSignService = locator(); class BaseAppClient { @@ -40,12 +39,12 @@ class BaseAppClient { post(String endPoint, {required Map body, - required Function(dynamic response, int statusCode) onSuccess, - required Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - bool isExternal = false, - bool isRCService = false, - bool bypassConnectionCheck = false}) async { + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false, + bool isRCService = false, + bool bypassConnectionCheck = false}) async { String url; if (isExternal) { url = endPoint; @@ -56,25 +55,20 @@ class BaseAppClient { url = BASE_URL + endPoint; } try { - String? pharmacyToken = - await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + String? pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); - Map headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; + Map headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}; if (!isExternal) { String? token = await sharedPref.getString(TOKEN); - String? languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + String? languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); if (endPoint == SEND_ACTIVATION_CODE) { languageID = 'en'; } if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID + ? body['SetupID'] + : SETUP_ID : SETUP_ID; } @@ -87,8 +81,8 @@ class BaseAppClient { body['LanguageID'] = body['LanguageID'] == 'ar' ? 1 : body['LanguageID'] == 'en' - ? 2 - : body['LanguageID']; + ? 2 + : body['LanguageID']; } else { body['LanguageID'] = Provider.of(AppGlobal.context, listen: false).isArabic ? 1 : 2; } @@ -120,16 +114,16 @@ class BaseAppClient { if (body.containsKey('isDentalAllowedBackend')) { body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; } body['DeviceTypeID'] = Platform.isIOS ? 1 : await Utils.isGoogleServicesAvailable() - ? 2 - : 3; + ? 2 + : 3; if (!body.containsKey('IsPublicRequest')) { // if (!body.containsKey('PatientType')) { @@ -166,17 +160,14 @@ class BaseAppClient { if (user != null) { body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token; - body['PatientID'] = body['PatientID'] != null - ? body['PatientID'] - : user['PatientID']; + body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : user['OutSA'] + ? body['PatientOutSA'] + : user['OutSA'] : user['OutSA']; - body['SessionID'] = getSessionId( - body['TokenID'] != null ? body['TokenID'] : ""); //getSe + body['SessionID'] = getSessionId(body['TokenID'] != null ? body['TokenID'] : ""); //getSe // body['SessionID'] = body['TokenID']; //getSe // headers = { @@ -193,7 +184,7 @@ class BaseAppClient { // body['IdentificationNo'] = 1023854217; // body['MobileNo'] = "531940021"; //0560717232 - // body['PatientID'] = 283093; //4609100 + // body['PatientID'] = 1231755; //4609100 // body['TokenID'] = "@dm!n"; // Patient ID: 3027574 @@ -202,21 +193,23 @@ class BaseAppClient { body.removeWhere((key, value) => key == null || value == null); + // if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { + // url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; + // body['TokenID'] = "@dm!n"; + // } + // if (AppGlobal.isNetworkDebugEnabled) { - print("URL : $url"); - final jsonBody = json.encode(body); - print(jsonBody); + debugPrint("URL : $url"); + final jsonBody = json.encode(body); + debugPrint(jsonBody); // } - if (await Utils.checkConnection( - bypassConnectionCheck: bypassConnectionCheck)) { - final response = await http.post(Uri.parse(url.trim()), - body: json.encode(body), headers: headers); + if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) { + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); final int statusCode = response.statusCode; if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); - logApiEndpointError( - endPoint, 'Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { // var decoded = utf8.decode(response.bodyBytes); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -230,12 +223,8 @@ class BaseAppClient { onSuccess(parsed, statusCode); } else { if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (parsed['ErrorType'] == 2) { await logout(); @@ -254,46 +243,28 @@ class BaseAppClient { // if (parsed != null) { // onSuccess(parsed, statusCode); // } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); // logout(); // } } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { onSuccess(parsed, statusCode); } else { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { - onFailure("Server Error found with no available message", - statusCode); - logApiEndpointError( - endPoint, - "Server Error found with no available message", - statusCode); + onFailure("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure(parsed['ErrorSearchMsg'], statusCode); - logApiEndpointError( - endPoint, parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); } } else { - onFailure( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); - logApiEndpointError(endPoint, - parsed['message'] ?? parsed['message'], statusCode); + onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } } } @@ -305,18 +276,11 @@ class BaseAppClient { onSuccess(parsed, statusCode); } else { if (parsed['message'] != null) { - onFailure( - parsed['message'] ?? parsed['message'], statusCode); - logApiEndpointError(endPoint, - parsed['message'] ?? parsed['message'], statusCode); + onFailure(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -325,23 +289,17 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); onFailure(e.toString(), -1); - _analytics.errorTracking - .log(endPoint, error: "api exception: $e - API Path: $url"); + _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url"); } } postPharmacy(String endPoint, - {Map? body, - Function(dynamic response, int statusCode)? onSuccess, - Function(String error, int statusCode)? onFailure, - bool isAllowAny = false, - bool isExternal = false}) async { + {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); String url; @@ -358,16 +316,13 @@ class BaseAppClient { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': pharmacyToken ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", }; if (!isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); // if (body.containsKey('SetupID')) { // body['SetupID'] = body.containsKey('SetupID') @@ -429,14 +384,12 @@ class BaseAppClient { print("Headers : ${json.encode(headers)}"); if (await Utils.checkConnection()) { - final response = await http.post(Uri.parse(url.trim()), - body: json.encode(body), headers: headers); + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); final int statusCode = response.statusCode; // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure!('Error While Fetching data', statusCode); - logApiEndpointError( - endPoint, 'Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -444,12 +397,8 @@ class BaseAppClient { onSuccess!(parsed, statusCode); } else { if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (isAllowAny) { onSuccess!(parsed, statusCode); @@ -464,56 +413,29 @@ class BaseAppClient { if (parsed != null) { onSuccess!(parsed, statusCode); } else { - onFailure!( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, 'session logged out', statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, 'session logged out', statusCode); logout(); } } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess!(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { onSuccess!(parsed, statusCode); } else { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { - onFailure!("Server Error found with no available message", - statusCode); - logApiEndpointError( - endPoint, - "Server Error found with no available message", - statusCode); + onFailure!("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure!(parsed['ErrorSearchMsg'], statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorSearchMsg'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else { - onFailure!( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } else if (!parsed['IsAuthenticated']) { @@ -525,22 +447,11 @@ class BaseAppClient { onSuccess!(parsed, statusCode); } else { if (parsed['message'] != null) { - onFailure!( - parsed['message'] ?? parsed['message'], statusCode); - logApiEndpointError( - endPoint, - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } else { - onFailure!( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -548,8 +459,7 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); @@ -560,18 +470,18 @@ class BaseAppClient { Future navigateToAppUpdate(context, String text) async { Navigator.pushAndRemoveUntil( - locator().navigatorKey.currentContext!, + locator().navigatorKey.currentContext!, MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)), - (Route route) => false, + (Route route) => false, ); } get(String endPoint, {required Function(dynamic response, int statusCode) onSuccess, - required Function(String error, int statusCode) onFailure, - Map? queryParams, - bool isExternal = false, - bool isRCService = false}) async { + required Function(String error, int statusCode) onFailure, + Map? queryParams, + bool isExternal = false, + bool isRCService = false}) async { String url; if (isExternal) { url = endPoint; @@ -592,10 +502,7 @@ class BaseAppClient { if (await Utils.checkConnection()) { final response = await http.get( Uri.parse(url.trim()), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, + headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, ); final int statusCode = response.statusCode; // print("statusCode :$statusCode"); @@ -609,17 +516,16 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } getPharmacy(String endPoint, {required Function(dynamic response, int statusCode) onSuccess, - required Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - bool isExternal = false, - Map? queryParams}) async { + required Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false, + Map? queryParams}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); @@ -642,9 +548,7 @@ class BaseAppClient { 'Content-Type': 'text/html; charset=utf-8', 'Accept': 'application/json', 'Authorization': token ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", // 'Host': "mdlaboratories.com", @@ -654,19 +558,14 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode == 401) { - onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, - statusCode); - logApiEndpointError( - endPoint, - TranslationBase.of(AppGlobal.context).pharmacyRelogin, - statusCode); + onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); + logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); Navigator.of(AppGlobal.context).pushNamed(HOME); } else { var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); // print(bodyUtf); onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode); - logApiEndpointError( - endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode); + logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode); } } else { // var parsed = json.decode(response.body.toString()); @@ -675,25 +574,23 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simplePost( - String fullUrl, { - required Map body, - required Map headers, - required Function(dynamic response, int statusCode) onSuccess, - required Function(String error, int statusCode) onFailure, - }) async { + String fullUrl, { + required Map body, + required Map headers, + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + }) async { String url = fullUrl; // print("URL Query String: $url"); // print("body: $body"); if (await Utils.checkConnection()) { - headers!.addAll( - {'Content-Type': 'application/json', 'Accept': 'application/json'}); + headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.post( Uri.parse(url.trim()), body: json.encode(body), @@ -701,12 +598,7 @@ class BaseAppClient { ); final int statusCode = response.statusCode; // print("statusCode :$statusCode"); - if (await handleUnauthorized(statusCode, forUrl: fullUrl)) - simplePost(fullUrl, - onFailure: onFailure, - onSuccess: onSuccess, - body: body, - headers: headers); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); // print(response.body.toString()); @@ -718,16 +610,12 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simpleGet(String fullUrl, - {Function(dynamic response, int statusCode)? onSuccess, - Function(String error, int statusCode)? onFailure, - Map? queryParams, - Map? headers}) async { + {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async { headers = headers ?? {}; String url = fullUrl; @@ -739,8 +627,7 @@ class BaseAppClient { } if (await Utils.checkConnection()) { - headers.addAll( - {'Content-Type': 'application/json', 'Accept': 'application/json'}); + headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.get( Uri.parse(url.trim()), headers: headers, @@ -748,12 +635,7 @@ class BaseAppClient { final int statusCode = response.statusCode; // print("statusCode :$statusCode"); - if (await handleUnauthorized(statusCode, forUrl: fullUrl)) - simpleGet(fullUrl, - onFailure: onFailure, - onSuccess: onSuccess, - headers: headers, - queryParams: queryParams); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure!('Error While Fetching data', statusCode); @@ -763,22 +645,17 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simplePut(String fullUrl, - {Map? body, - Map? headers, - Function(dynamic response, int statusCode)? onSuccess, - Function(String error, int statusCode)? onFailure}) async { + {Map? body, Map? headers, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async { String url = fullUrl; // print("URL Query String: $url"); if (await Utils.checkConnection()) { - headers!.addAll( - {'Content-Type': 'application/json', 'Accept': 'application/json'}); + headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.put( Uri.parse(url.trim()), body: json.encode(body), @@ -787,12 +664,7 @@ class BaseAppClient { final int statusCode = response.statusCode; // print("statusCode :$statusCode"); - if (await handleUnauthorized(statusCode, forUrl: fullUrl)) - simplePut(fullUrl, - onFailure: onFailure, - onSuccess: onSuccess, - headers: headers, - body: body); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure!('Error While Fetching data', statusCode); @@ -802,16 +674,12 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simpleDelete(String fullUrl, - {Function(dynamic response, int statusCode)? onSuccess, - Function(String error, int statusCode)? onFailure, - Map? queryParams, - Map? headers}) async { + {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async { String url = fullUrl; // print("URL Query String: $url"); @@ -823,8 +691,7 @@ class BaseAppClient { } if (await Utils.checkConnection()) { - headers!.addAll( - {'Content-Type': 'application/json', 'Accept': 'application/json'}); + headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.delete( Uri.parse(url.trim()), headers: headers, @@ -832,12 +699,7 @@ class BaseAppClient { final int statusCode = response.statusCode; // print("statusCode :$statusCode"); - if (await handleUnauthorized(statusCode, forUrl: fullUrl)) - simpleDelete(fullUrl, - onFailure: onFailure, - onSuccess: onSuccess, - queryParams: queryParams, - headers: headers); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure!('Error While Fetching data', statusCode); @@ -847,13 +709,11 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } - Future handleUnauthorized(int statusCode, - {required String forUrl}) async { + Future handleUnauthorized(int statusCode, {required String forUrl}) async { if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { final token = await generatePackagesToken(); packagesAuthHeader['Authorization'] = 'Bearer $token'; @@ -866,10 +726,8 @@ class BaseAppClient { await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID); await authenticatedUserObject.getUser(); - Provider.of(AppGlobal.context, listen: false).isLogin = - false; - var model = - Provider.of(AppGlobal.context, listen: false); + Provider.of(AppGlobal.context, listen: false).isLogin = false; + var model = Provider.of(AppGlobal.context, listen: false); _vitalSignService.weightKg = ""; _vitalSignService.heightCm = ""; model.setState(0, 0, false, null); @@ -884,8 +742,7 @@ class BaseAppClient { static defaultHttpParameters() async { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); var params = {}; if (user != null) { @@ -905,11 +762,7 @@ class BaseAppClient { } pharmacyPost(String endPoint, - {Map? body, - Function(dynamic response, int statusCode)? onSuccess, - Function(String error, int statusCode)? onFailure, - bool isAllowAny = false, - bool isExternal = false}) async { + {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); String url; @@ -921,14 +774,13 @@ class BaseAppClient { try { if (isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); if (body!.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID + ? body['SetupID'] + : SETUP_ID : SETUP_ID; } @@ -940,15 +792,15 @@ class BaseAppClient { body['generalid'] = GENERAL_ID; body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : user['OutSA'] + ? body['PatientOutSA'] + : user['OutSA'] : user['OutSA']; if (body.containsKey('isDentalAllowedBackend')) { body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; } @@ -957,24 +809,22 @@ class BaseAppClient { if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') ? body['PatientType'] != null - ? body['PatientType'] - : user['PatientType'] != null - ? user['PatientType'] - : user['PatientType'] + ? body['PatientType'] + : user['PatientType'] != null + ? user['PatientType'] + : user['PatientType'] : user['PatientType']; body['PatientTypeID'] = body.containsKey('PatientTypeID') ? body['PatientTypeID'] != null - ? body['PatientTypeID'] - : user['PatientType'] != null - ? user['PatientType'] - : user['PatientType'] + ? body['PatientTypeID'] + : user['PatientType'] != null + ? user['PatientType'] + : user['PatientType'] : user['PatientType']; if (user != null) { body['TokenID'] = token; - body['PatientID'] = body['PatientID'] != null - ? body['PatientID'] - : user['PatientID']; + body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; body['PatientOutSA'] = user['OutSA']; // body['SessionID'] = SESSION_ID; //getSessionId(token); } @@ -986,14 +836,11 @@ class BaseAppClient { var ss = json.encode(body); if (await Utils.checkConnection()) { - final response = await http - .post(Uri.parse(url.trim()), body: json.encode(body), headers: { + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': token ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", }); @@ -1001,15 +848,8 @@ class BaseAppClient { // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { var parsed = json.decode(utf8.decode(response.bodyBytes)); - onFailure!( - parsed['error']['ErrorEndUserMsgN'] ?? - 'Error While Fetching data', - statusCode); - logApiEndpointError( - endPoint, - parsed['error']['ErrorEndUserMsgN'] ?? - 'Error While Fetching data', - statusCode); + onFailure!(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); + logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -1017,8 +857,7 @@ class BaseAppClient { onSuccess!(parsed, statusCode); } else { if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); } if (isAllowAny) { onSuccess!(parsed, statusCode); @@ -1033,47 +872,25 @@ class BaseAppClient { if (parsed != null) { onSuccess!(parsed, statusCode); } else { - onFailure!( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); logout(); } } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess!(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { - onFailure!("Server Error found with no available message", - statusCode); - logApiEndpointError( - endPoint, - "Server Error found with no available message", - statusCode); + onFailure!("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure!(parsed['ErrorSearchMsg'], statusCode); - logApiEndpointError( - endPoint, parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); } } else { - onFailure!( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else if (!parsed['IsAuthenticated']) { await logout(); @@ -1084,18 +901,11 @@ class BaseAppClient { onSuccess!(parsed, statusCode); } else { if (parsed['message'] != null) { - onFailure!( - parsed['message'] ?? parsed['message'], statusCode); - logApiEndpointError(endPoint, - parsed['message'] ?? parsed['message'], statusCode); + onFailure!(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } else { - onFailure!( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logApiEndpointError( - endPoint, - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -1103,8 +913,7 @@ class BaseAppClient { } } else { onFailure!('Please Check The Internet Connection', -1); - _analytics.errorTracking - .log("internet_connectivity", error: "no internet available"); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); @@ -1116,15 +925,11 @@ class BaseAppClient { Future generatePackagesToken() async { var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN; var body = { - "api_client": { - "client_id": "a4ab6be4-424f-4836-b032-46caed88e184", - "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c" - } + "api_client": {"client_id": "a4ab6be4-424f-4836-b032-46caed88e184", "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"} }; String? token; final completer = Completer(); - simplePost(url, body: body, headers: {}, - onSuccess: (dynamic stringResponse, int statusCode) { + simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); token = jsonResponse['auth_token']; diff --git a/lib/core/service/medical/labs_service.dart b/lib/core/service/medical/labs_service.dart index 77ea728e..8ca246a0 100644 --- a/lib/core/service/medical/labs_service.dart +++ b/lib/core/service/medical/labs_service.dart @@ -124,12 +124,15 @@ class LabsService extends BaseService { return Future.value(localRes); } - Future updateWorkplaceName(String workplaceName, String workplaceNameAR, int requestNumber, String setupID, int projectID) async { + Future updateWorkplaceName(String workplaceName, String workplaceNameAR, String occupation, String occupationAR, int requestNumber, String setupID, int projectID) async { + // Future updateWorkplaceName(String workplaceName, String workplaceNameAR, int requestNumber, String setupID, int projectID) async { hasError = false; Map body = Map(); body['Placeofwork'] = workplaceName; - body['Placeofworkar'] = workplaceNameAR; + body['PlaceofworkAr'] = workplaceNameAR; + body['Occupation'] = occupation; + body['OccupationAr'] = occupationAR; body['Req_ID'] = requestNumber; body['TargetSetupID'] = setupID; body['ProjectID'] = projectID; diff --git a/lib/core/service/medical/medical_service.dart b/lib/core/service/medical/medical_service.dart index a77729c9..445f5ab6 100644 --- a/lib/core/service/medical/medical_service.dart +++ b/lib/core/service/medical/medical_service.dart @@ -72,11 +72,15 @@ class MedicalService extends BaseService { dynamic localRes; await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, onSuccess: (response, statusCode) async { localRes = response; + freeSlots.clear(); + localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); }, onFailure: (String error, int statusCode) { - throw error; + hasError = true; + super.error = error; + // throw error; }, body: request); - freeSlots.clear(); - localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); + // freeSlots.clear(); + // localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); // localRes['List_DoctorWorkingHoursTable'].forEach((item) => // {doctorScheduleResponse.add(DoctorScheduleResponse.fromJson(item))}); } diff --git a/lib/core/service/medical/prescriptions_service.dart b/lib/core/service/medical/prescriptions_service.dart index 71a24a39..c5b1a16f 100644 --- a/lib/core/service/medical/prescriptions_service.dart +++ b/lib/core/service/medical/prescriptions_service.dart @@ -98,6 +98,7 @@ class PrescriptionsService extends BaseService { await baseAppClient.post(prescriptions.isInOutPatient! ? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT, onSuccess: (dynamic response, int statusCode) { prescriptionReportList.clear(); prescriptionReportEnhList.clear(); + prescriptionReportListINP.clear(); isMedDeliveryAllowed = response['IsHomeMedicineDeliverySupported']; if (prescriptions.isInOutPatient!) { response['ListPRM'].forEach((prescriptions) { @@ -120,8 +121,9 @@ class PrescriptionsService extends BaseService { isDentalAllowedBackend: false, ); - Future sendPrescriptionEmail(String appointmentDate, int patientID, String clinicName, String doctorName, int doctorID, int projectID) async { + Future sendPrescriptionEmail(String appointmentDate, int patientID, String clinicName, String doctorName, int doctorID, int projectID, bool isInOutPatient) async { _requestSendPrescriptionEmail.listPrescriptions = prescriptionReportList; + _requestSendPrescriptionEmail.listPrescriptionsINP = prescriptionReportListINP; _requestSendPrescriptionEmail.appointmentDate = appointmentDate; _requestSendPrescriptionEmail.patientID = patientID; _requestSendPrescriptionEmail.clinicName = clinicName; diff --git a/lib/core/viewModels/medical/prescriptions_view_model.dart b/lib/core/viewModels/medical/prescriptions_view_model.dart index a3816d92..8ad23b9b 100644 --- a/lib/core/viewModels/medical/prescriptions_view_model.dart +++ b/lib/core/viewModels/medical/prescriptions_view_model.dart @@ -114,9 +114,9 @@ class PrescriptionsViewModel extends BaseViewModel { } } - sendPrescriptionEmail({required String appointmentDate, required int patientID, required String clinicName, required String doctorName, required int doctorID, required String mes, required int projectID}) async { + sendPrescriptionEmail({required String appointmentDate, required int patientID, required String clinicName, required String doctorName, required int doctorID, required String mes, required int projectID, required bool isInOutPatient}) async { setState(ViewState.BusyLocal); - await _prescriptionsService.sendPrescriptionEmail(appointmentDate, patientID, clinicName, doctorName, doctorID, projectID); + await _prescriptionsService.sendPrescriptionEmail(appointmentDate, patientID, clinicName, doctorName, doctorID, projectID, isInOutPatient); if (_prescriptionsService.hasError) { error = _prescriptionsService.error!; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index 398b3afe..238ee0f5 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -18,7 +18,10 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; +import '../../models/Appointments/DoctorListResponse.dart'; + bool isAppArabic = false; + class ProjectViewModel extends BaseViewModel { GAnalytics get analytics => locator(); @@ -30,7 +33,7 @@ class ProjectViewModel extends BaseViewModel { AppSharedPreferences sharedPref = AppSharedPreferences(); Locale _appLocale = Locale('ar'); String currentLanguage = 'ar'; - bool _isArabic = false; + bool _isArabic = true; bool isInternetConnection = true; bool isLoading = false; bool isError = false; @@ -38,6 +41,7 @@ class ProjectViewModel extends BaseViewModel { dynamic searchvalue; bool isLogin = false; bool _isAllAppointmentsLoaded = false; + bool get isAllAppointmentsLoaded => _isAllAppointmentsLoaded; bool isPatientAdmitted = false; bool patientHasAdmissionRequest = false; @@ -45,15 +49,36 @@ class ProjectViewModel extends BaseViewModel { GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel(); GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel(); + bool isIndoorNavigationEnabled = true; + + int waitingAppointmentProjectID = 0; + DoctorList? waitingAppointmentDoctor; + String waitingAppointmentNFCCode = ""; + + setWaitingAppointmentDoctor(DoctorList waitingAppointmentDoctor) { + this.waitingAppointmentDoctor = waitingAppointmentDoctor; + notifyListeners(); + } + + setWaitingAppointmentNFCCode(String waitingAppointmentNFCCode) { + this.waitingAppointmentNFCCode = waitingAppointmentNFCCode; + notifyListeners(); + } + + setWaitingAppointmentProjectID(int projectID) { + this.waitingAppointmentProjectID = projectID; + notifyListeners(); + } + void setIsAllAppointmentsLoaded(bool value) { _isAllAppointmentsLoaded = value; notifyListeners(); } - RegisterInfoResponse _registerInfo = RegisterInfoResponse(); RegisterInfoResponse get registerInfo => _registerInfo; + dynamic get searchValue => searchvalue; Locale get appLocal => _appLocale; @@ -70,7 +95,9 @@ class ProjectViewModel extends BaseViewModel { List _projectDetailListModel = []; List get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser; + List get vidaPlusProjectList => _vidaPlusProjectListModel; + List get hMCProjectListModel => _hMCProjectListModel; List get projectDetailListModel => _projectDetailListModel; @@ -137,6 +164,11 @@ class ProjectViewModel extends BaseViewModel { notifyListeners(); } + setIsIndoorNavigationEnabled(bool isEnabled) { + this.isIndoorNavigationEnabled = isEnabled; + notifyListeners(); + } + setPatientHasAdmissionRequest(bool hasAdmissionRequest) { this.patientHasAdmissionRequest = hasAdmissionRequest; notifyListeners(); @@ -200,8 +232,6 @@ class ProjectViewModel extends BaseViewModel { notifyListeners(); } - - bool havePrivilege(int id) { bool isHavePrivilege = false; try { @@ -222,7 +252,7 @@ class ProjectViewModel extends BaseViewModel { @override void dispose() { - if (subscription != null) subscription.cancel(); + if (subscription != null) subscription.cancel(); super.dispose(); } diff --git a/lib/main.dart b/lib/main.dart index a0a584a5..815bea40 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,6 +14,8 @@ import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; @@ -27,8 +29,19 @@ import 'pages/pharmacies/compare-list.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); + + // Pass all uncaught "fatal" errors from the framework to Crashlytics + FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; + + // Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics + PlatformDispatcher.instance.onError = (error, stack) { + if (!kDebugMode) FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + return true; + }; + setupLocator(); HttpOverrides.global = MyHttpOverrides(); + runApp(MyApp()); } @@ -55,8 +68,6 @@ class _MyApp extends State { //0567184134 mobile //246305493 - - // checkForUpdate() { // // todo need to verify 'imp' // InAppUpdate.checkForUpdate().then((info) { @@ -140,14 +151,12 @@ class _MyApp extends State { ], child: Consumer( builder: (context, projectProvider, child) => MaterialApp( - builder: (_, mchild) { return MediaQuery( - data: MediaQuery.of(context).copyWith( - textScaler: TextScaler.linear(1.0), - ), //set desired text scale factor here - child: mchild! - ); + data: MediaQuery.of(context).copyWith( + textScaler: TextScaler.linear(1.0), + ), //set desired text scale factor here + child: mchild!); // Container( // color: Colors.blue, // )); diff --git a/lib/models/Appointments/DoctorListResponse.dart b/lib/models/Appointments/DoctorListResponse.dart index 8c6ad3f6..c7ecdfcd 100644 --- a/lib/models/Appointments/DoctorListResponse.dart +++ b/lib/models/Appointments/DoctorListResponse.dart @@ -41,8 +41,11 @@ class DoctorList { dynamic serviceID; String? setupID; List? speciality; + List? specialityN; dynamic workingHours; dynamic decimalDoctorRate; + String? projectBottomName; + String? projectTopName; DoctorList( {this.clinicID, @@ -87,8 +90,11 @@ class DoctorList { this.serviceID, this.setupID, this.speciality, + this.specialityN, this.workingHours, - this.decimalDoctorRate}); + this.decimalDoctorRate, + this.projectBottomName, + this.projectTopName}); DoctorList.fromJson(Map json) { clinicID = json['ClinicID']; @@ -133,8 +139,11 @@ class DoctorList { serviceID = json['ServiceID']; setupID = json['SetupID']; if (json.containsKey('Speciality') && json['Speciality'] != null) speciality = json['Speciality'].cast(); + if (json.containsKey('SpecialityN') && json['SpecialityN'] != null) specialityN = json['SpecialityN'].cast(); workingHours = json['WorkingHours']; decimalDoctorRate = json['DecimalDoctorRate']; + projectBottomName = json['ProjectNameBottom']; + projectTopName = json['ProjectNameTop']; } Map toJson() { @@ -180,18 +189,25 @@ class DoctorList { data['ServiceID'] = this.serviceID; data['SetupID'] = this.setupID; data['Speciality'] = this.speciality; + data['SpecialityN'] = this.specialityN; data['WorkingHours'] = this.workingHours; data['DecimalDoctorRate'] = this.decimalDoctorRate; return data; } + + String getProjectCompleteName(){ + return "${this.projectTopName} ${this.projectBottomName}"; + } } class PatientDoctorAppointmentList { String? filterName = ""; String? distanceInKMs = ""; List? patientDoctorAppointmentList = []; + String? projectTopName = ""; + String? projectBottomName = ""; - PatientDoctorAppointmentList({this.filterName, this.distanceInKMs, DoctorList? patientDoctorAppointment}) { + PatientDoctorAppointmentList({this.filterName, this.distanceInKMs, this.projectTopName, this.projectBottomName, DoctorList? patientDoctorAppointment}) { patientDoctorAppointmentList!.add(patientDoctorAppointment!); } } diff --git a/lib/models/Appointments/PatientPackageComponent b/lib/models/Appointments/PatientPackageComponent new file mode 100644 index 00000000..e69de29b diff --git a/lib/models/Appointments/PatientPackageComponent.dart b/lib/models/Appointments/PatientPackageComponent.dart new file mode 100644 index 00000000..26ce9229 --- /dev/null +++ b/lib/models/Appointments/PatientPackageComponent.dart @@ -0,0 +1,59 @@ +class PatientPackageComponent { + List? patientPackageComponents; + + PatientPackageComponent({this.patientPackageComponents}); + + PatientPackageComponent.fromJson(Map json) { + if (json['PatientPackageComponents'] != null) { + patientPackageComponents = []; + json['PatientPackageComponents'].forEach((v) { + patientPackageComponents!.add(new PatientPackageComponents.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.patientPackageComponents != null) { + data['PatientPackageComponents'] = this.patientPackageComponents!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class PatientPackageComponents { + int? invoiceNo; + int? lineItemNo; + String? procedureID; + String? procedureName; + int? projectID; + int? sequence; + String? setupID; + num? invoiceNo_VP; + + PatientPackageComponents({this.invoiceNo, this.lineItemNo, this.procedureID, this.procedureName, this.projectID, this.sequence, this.setupID, this.invoiceNo_VP}); + + PatientPackageComponents.fromJson(Map json) { + invoiceNo = json['InvoiceNo']; + lineItemNo = json['LineItemNo']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + projectID = json['ProjectID']; + sequence = json['Sequence']; + setupID = json['SetupID']; + invoiceNo_VP = json['InvoiceNo_VP']; + } + + Map toJson() { + final Map data = new Map(); + data['InvoiceNo'] = this.invoiceNo; + data['LineItemNo'] = this.lineItemNo; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProjectID'] = this.projectID; + data['Sequence'] = this.sequence; + data['SetupID'] = this.setupID; + data['InvoiceNo_VP'] = this.invoiceNo_VP; + return data; + } +} diff --git a/lib/models/InPatientServices/get_admission_info_response_model.dart b/lib/models/InPatientServices/get_admission_info_response_model.dart index 85fe08d1..901adda8 100644 --- a/lib/models/InPatientServices/get_admission_info_response_model.dart +++ b/lib/models/InPatientServices/get_admission_info_response_model.dart @@ -19,6 +19,9 @@ class GetAdmissionInfoResponseModel { int? status; String? statusDesc; String? statusDescN; + String? clinicName; + String? doctorName; + String? projectName; GetAdmissionInfoResponseModel( {this.setupID, @@ -40,7 +43,10 @@ class GetAdmissionInfoResponseModel { this.approvalNo, this.status, this.statusDesc, - this.statusDescN}); + this.statusDescN, + this.clinicName, + this.doctorName, + this.projectName}); GetAdmissionInfoResponseModel.fromJson(Map json) { setupID = json['SetupID']; @@ -63,6 +69,9 @@ class GetAdmissionInfoResponseModel { status = json['Status']; statusDesc = json['StatusDesc']; statusDescN = json['StatusDescN']; + clinicName = json['ClinicName']; + doctorName = json['DoctorName']; + projectName = json['ProjectName']; } Map toJson() { @@ -87,6 +96,9 @@ class GetAdmissionInfoResponseModel { data['Status'] = this.status; data['StatusDesc'] = this.statusDesc; data['StatusDescN'] = this.statusDescN; + data['ClinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['ProjectName'] = this.projectName; return data; } } diff --git a/lib/models/LiveCare/ERAppointmentFeesResponse.dart b/lib/models/LiveCare/ERAppointmentFeesResponse.dart index b8a88aba..3deaa05b 100644 --- a/lib/models/LiveCare/ERAppointmentFeesResponse.dart +++ b/lib/models/LiveCare/ERAppointmentFeesResponse.dart @@ -24,6 +24,8 @@ class GetERAppointmentFeesList { String? companyName; bool? isInsured; bool? isShowInsuranceUpdateModule; + bool? isCash; + bool? isEligible; String? tax; String? total; String? currency; @@ -41,6 +43,8 @@ class GetERAppointmentFeesList { amount = json['Amount']; companyName = json['CompanyName']; isInsured = json['IsInsured']; + isCash = json['IsCash']; + isEligible = json['IsEligible']; isShowInsuranceUpdateModule = json['IsShowInsuranceUpdateModule']; tax = json['Tax']; total = json['Total']; diff --git a/lib/models/LiveCare/IncomingCallData.dart b/lib/models/LiveCare/IncomingCallData.dart index 06cfd150..e357a5df 100644 --- a/lib/models/LiveCare/IncomingCallData.dart +++ b/lib/models/LiveCare/IncomingCallData.dart @@ -6,7 +6,7 @@ class IncomingCallData { String? notificationForeground; String? count; String? message; - String? appointmentNo; + String? appointmentNo; // 1 for Video call, 2 for Audio call String? title; String? projectID; String? notificationType; diff --git a/lib/models/SmartWatch/WeeklyHeartRateResModel.dart b/lib/models/SmartWatch/WeeklyHeartRateResModel.dart index 1c21c22d..26341ee0 100644 --- a/lib/models/SmartWatch/WeeklyHeartRateResModel.dart +++ b/lib/models/SmartWatch/WeeklyHeartRateResModel.dart @@ -8,7 +8,7 @@ class WeeklyHeartRateResModel { {this.valueAvg, this.machineDate, this.medCategoryID, this.patientID}); WeeklyHeartRateResModel.fromJson(Map json) { - num value = json['ValueAvg']; + num value = json['ValueAvg'] != null ? json['ValueAvg'] : 0.0; valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; machineDate = json['MachineDate']; medCategoryID = json['MedCategoryID']; diff --git a/lib/models/SmartWatch/YearlyHeartRateResModel.dart b/lib/models/SmartWatch/YearlyHeartRateResModel.dart index 331d5adb..3d81ff2c 100644 --- a/lib/models/SmartWatch/YearlyHeartRateResModel.dart +++ b/lib/models/SmartWatch/YearlyHeartRateResModel.dart @@ -15,7 +15,7 @@ class YearlyHeartRateResModel { this.year}); YearlyHeartRateResModel.fromJson(Map json) { - num value = json['ValueAvg']; + num value = json['ValueAvg'] != null ? json['ValueAvg'] : 0.0; valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; medCategoryID = json['MedCategoryID']; month = json['Month']; diff --git a/lib/models/hmg_services.dart b/lib/models/hmg_services.dart index c4163bd4..793800fa 100644 --- a/lib/models/hmg_services.dart +++ b/lib/models/hmg_services.dart @@ -4,6 +4,7 @@ class HmgServices { String subTitle; String icon; bool isLogin; + bool isLocked; - HmgServices(this.action, this.title, this.subTitle, this.icon,this.isLogin); + HmgServices(this.action, this.title, this.subTitle, this.icon, this.isLogin, {this.isLocked = false}); } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart index 536af3cd..94379af8 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart @@ -100,7 +100,7 @@ class ConfirmDialog extends StatelessWidget { onClick(); Navigator.pop(context); }, - textColor: Theme.of(context).backgroundColor), + textColor: CustomColors.white), ), ], ), diff --git a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart index b9eefe08..3b5d585e 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.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'; @@ -367,11 +368,11 @@ class _EReferralConfirmSMSDialogState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart index dfccb11b..ee8f5b92 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart @@ -30,28 +30,18 @@ class NewHomeHealthCareStepTowPage extends StatefulWidget { final Function(PickResult)? onPick; final double? latitude; final double? longitude; - final PatientERInsertPresOrderRequestModel? - patientERInsertPresOrderRequestModel; + final PatientERInsertPresOrderRequestModel? patientERInsertPresOrderRequestModel; final Function? changePageViewIndex; final HomeHealthCareViewModel model; - const NewHomeHealthCareStepTowPage( - {Key? key, - this.onPick, - this.latitude, - this.longitude, - this.patientERInsertPresOrderRequestModel, - this.changePageViewIndex, - required this.model}) + const NewHomeHealthCareStepTowPage({Key? key, this.onPick, this.latitude, this.longitude, this.patientERInsertPresOrderRequestModel, this.changePageViewIndex, required this.model}) : super(key: key); @override - _NewHomeHealthCareStepTowPageState createState() => - _NewHomeHealthCareStepTowPageState(); + _NewHomeHealthCareStepTowPageState createState() => _NewHomeHealthCareStepTowPageState(); } -class _NewHomeHealthCareStepTowPageState - extends State { +class _NewHomeHealthCareStepTowPageState extends State { double latitude = 0; double longitude = 0; AddressInfo? _selectedAddress; @@ -88,8 +78,7 @@ class _NewHomeHealthCareStepTowPageState } void _getUserLocation() async { - if (await this.sharedPref.getDouble(USER_LAT) != null && - await this.sharedPref.getDouble(USER_LONG) != null) { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { var lat = await this.sharedPref.getDouble(USER_LAT); var long = await this.sharedPref.getDouble(USER_LONG); latitude = lat; @@ -97,8 +86,7 @@ class _NewHomeHealthCareStepTowPageState currentPostion = LatLng(lat, long); setMap(); } else { - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); locationUtils.getCurrentLocation(callBack: (value) { print(value); setMap(); @@ -138,8 +126,7 @@ class _NewHomeHealthCareStepTowPageState showCurrentLocation = true; }); } else { - latLong = widget - .model.addressesList[widget.model.addressesList.length - 1].latLong; + latLong = widget.model.addressesList[widget.model.addressesList.length - 1].latLong; } } @@ -178,8 +165,7 @@ class _NewHomeHealthCareStepTowPageState decoration: cardRadius(12), child: Container( child: InkWell( - onTap: () => - confirmSelectLocationDialog(widget.model.addressesList), + onTap: () => confirmSelectLocationDialog(widget.model.addressesList), child: Container( padding: EdgeInsets.all(8), width: double.infinity, @@ -212,28 +198,28 @@ class _NewHomeHealthCareStepTowPageState ), InkWell( onTap: () { - Navigator.push( - context, - FadePage( - page: LocationPage( - // latitude: latitude, - // longitude: longitude, - ), - ), - ).then((value) async { - print(value); - await widget.model.getCustomerAddresses(); - setState(() {}); - }); + // Navigator.push( + // context, + // FadePage( + // page: LocationPage( + // // latitude: latitude, + // // longitude: longitude, + // ), + // ), + // ).then((value) async { + // print(value); + // await widget.model.getCustomerAddresses(); + // setState(() {}); + // }); }, child: Padding( - padding: EdgeInsets.only(left: 12, right: 12, bottom: 16, top: 8), + padding: EdgeInsets.only(left: 12, right: 12, bottom: 16, top: 16), child: Row( children: [ - Icon(Icons.add_circle_outline_sharp), + Icon(Icons.location_on_outlined), mWidth(12), Text( - TranslationBase.of(context).addNewAddress, + TranslationBase.of(context).selectLocation, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, @@ -261,23 +247,18 @@ class _NewHomeHealthCareStepTowPageState ), ), Padding( - padding: - const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), child: DefaultButton( TranslationBase.of(context).continues, () { setState(() { - widget.patientERInsertPresOrderRequestModel!.latitude = - latitude; - widget.patientERInsertPresOrderRequestModel!.longitude = - longitude; + widget.patientERInsertPresOrderRequestModel!.latitude = latitude; + widget.patientERInsertPresOrderRequestModel!.longitude = longitude; }); - navigateTo( context, NewHomeHealthCareStepThreePage( - patientERInsertPresOrderRequestModel: - widget.patientERInsertPresOrderRequestModel, + patientERInsertPresOrderRequestModel: widget.patientERInsertPresOrderRequestModel, model: widget.model, ), ); @@ -319,8 +300,7 @@ class _NewHomeHealthCareStepTowPageState goToCurrentLocation() { Geolocator.getCurrentPosition().then((value) { - _selectedAddress = - AddressInfo(latLong: '${value.latitude},${value.longitude}'); + _selectedAddress = AddressInfo(latLong: '${value.latitude},${value.longitude}'); moveToLocation(LatLng(value.latitude, value.longitude)); }); } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart index 89091886..05b0d753 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.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'; @@ -36,9 +37,7 @@ class HomeHealthCareIndexPage extends StatelessWidget { SizedBox( height: 22, ), - Center( - child: Image.asset( - 'assets/images/AlHabibMedicalService/Wifi-AR.png')), + Center(child: Image.asset('assets/images/AlHabibMedicalService/Wifi-AR.png')), SizedBox( height: 77, ), @@ -53,13 +52,13 @@ class HomeHealthCareIndexPage extends StatelessWidget { width: MediaQuery.of(context).size.width * 0.9, child: SecondaryButton( onTap: () => Navigator.push( - context, - FadePage( - page: HomeHealthCarePage(), - ), - ), + context, + FadePage( + page: HomeHealthCarePage(), + ), + ), label: TranslationBase.of(context).loginRegister, - textColor: Theme.of(context).backgroundColor), + textColor: CustomColors.white), ), ], ), diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart index f23d175d..420f08f1 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart @@ -37,6 +37,7 @@ class _AllHabibMedicalSevicePage2State extends State AuthProvider authProvider = new AuthProvider(); WeatherService _weatherService = WeatherService(); double weatherNum = 30; + late ProjectViewModel projectViewModel; @override void initState() { @@ -235,7 +236,7 @@ class _AllHabibMedicalSevicePage2State extends State itemCount: hmgServices.length, padding: EdgeInsets.zero, itemBuilder: (BuildContext context, int index) { - return ServicesView(hmgServices[index], index, false); + return ServicesView(hmgServices[index], index, false, projectViewModel); }, ), ), diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart index d48247f8..cb1183ef 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -669,6 +669,7 @@ class _AnicllaryOrdersState extends State with SingleTic payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); log("failureResult: ${failureResult.toString()}"); AppToast.showErrorToast(message: failureResult.toString()); }, diff --git a/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart index df8d3cc8..a28c0d3e 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.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'; @@ -57,9 +58,7 @@ class H2OPageIndexPage extends StatelessWidget { onTap: () => Navigator.push(context, FadePage(page: H2OPage())), label: "Water Tracker", - textColor: Theme - .of(context) - .backgroundColor), + textColor: CustomColors.white), ), ], ), diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart index 66c50e5b..f3b88a60 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart @@ -190,7 +190,7 @@ class _BariatricsPageState extends State { } Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))) .then((value) { setState(() { // dropdownValue = null; diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart index 95bfdf0a..26222569 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart @@ -188,7 +188,7 @@ class _ResultPageState extends State { } Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))) .then((value) { setState(() { // dropdownValue = null; diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart index 33ff10b4..79060a2d 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart @@ -154,7 +154,7 @@ class BmrResultPage extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart index 94e7796c..79014ba2 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart @@ -150,7 +150,7 @@ class FatResult extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart index ac67f1d8..5844b006 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart @@ -155,7 +155,7 @@ class CalorieResultPage extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart index 99ab9ecb..29257ccc 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart @@ -176,7 +176,7 @@ class CarbsResult extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart index e1364e73..84dc5e5e 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart @@ -176,7 +176,7 @@ class DeliveryDueResult extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart index 40dae7c9..1fa9d2a9 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart @@ -214,7 +214,7 @@ class IdealBodyResult extends StatelessWidget { BariatricsService service = new BariatricsService(); List doctorsList = []; - List _patientDoctorAppointmentListHospital =[]; + List _patientDoctorAppointmentListHospital = []; service.getCalculationDoctors(calculationID: 4).then((res) { GifLoaderDialogUtils.hideDialog(context); @@ -253,7 +253,15 @@ class IdealBodyResult extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push( + context, + FadePage( + page: SearchResults( + isLiveCareAppointment: false, + doctorsList: doctorsList, + patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, + isDoctorSearchResult: false, + ))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart index 300e96fa..8af51a3d 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart @@ -186,7 +186,7 @@ class OvulationResult extends StatelessWidget { } }); - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital, isDoctorSearchResult: false,))); } } }).catchError((err) { diff --git a/lib/pages/AlHabibMedicalService/my_web_view.dart b/lib/pages/AlHabibMedicalService/my_web_view.dart index 1779b127..bd824cd4 100644 --- a/lib/pages/AlHabibMedicalService/my_web_view.dart +++ b/lib/pages/AlHabibMedicalService/my_web_view.dart @@ -4,31 +4,57 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; -class MyWebView extends StatelessWidget { +class MyWebView extends StatefulWidget { final String title; final String selectedUrl; - final Completer _controller = Completer(); - MyWebView({ required this.title, required this.selectedUrl, }); @override - Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: title, - isShowDecPage: false, - showNewAppBar: true, - showNewAppBarTitle: true, - body: WebView( - initialUrl: selectedUrl, - javascriptMode: JavascriptMode.unrestricted, - onWebViewCreated: (WebViewController webViewController) { - _controller.complete(webViewController); + State createState() => _MyWebViewState(); +} + +class _MyWebViewState extends State { + // final Completer _controller = Completer(); + late final WebViewController _controller; + + @override + void initState() { + super.initState(); + _controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. }, - )); + onPageStarted: (String url) {}, + onPageFinished: (String url) {}, + onHttpError: (HttpResponseError error) {}, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('https://www.youtube.com/')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse(widget.selectedUrl)); + } + + @override + Widget build(BuildContext context) { + return AppScaffold(isShowAppBar: true, appBarTitle: widget.title, isShowDecPage: false, showNewAppBar: true, showNewAppBarTitle: true, body: WebViewWidget(controller: _controller) + // WebView( + // initialUrl: widget.selectedUrl, + // javascriptMode: JavascriptMode.unrestricted, + // onWebViewCreated: (WebViewController webViewController) { + // _controller.complete(webViewController); + // }, + ); } } diff --git a/lib/pages/Blood/blood_donation_book_appointment.dart b/lib/pages/Blood/blood_donation_book_appointment.dart index a0b9f6f7..6485b2d8 100644 --- a/lib/pages/Blood/blood_donation_book_appointment.dart +++ b/lib/pages/Blood/blood_donation_book_appointment.dart @@ -445,7 +445,7 @@ class _BloodDonationBookAppointmentState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/Blood/new_text_Field.dart b/lib/pages/Blood/new_text_Field.dart index e6431f1f..61a97eb8 100644 --- a/lib/pages/Blood/new_text_Field.dart +++ b/lib/pages/Blood/new_text_Field.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -183,7 +184,8 @@ class _NewTextFieldsState extends State { validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + // style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ FilteringTextInputFormatter.digitsOnly, @@ -193,8 +195,8 @@ class _NewTextFieldsState extends State { decoration: InputDecoration( labelText: widget.hintText, labelStyle: TextStyle(color: Colors.black), - errorBorder: OutlineInputBorder(borderSide: BorderSide(color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), - focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), + errorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), + focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), enabledBorder: OutlineInputBorder( diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index b2ccf085..65dfa1b1 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -1,26 +1,38 @@ import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -28,6 +40,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; +import '../../models/Appointments/PatientPackageComponent.dart'; import 'book_reminder_page.dart'; import 'components/DocAvailableAppointments.dart'; @@ -41,7 +54,10 @@ class BookConfirm extends StatefulWidget { bool isLiveCareAppointment; int initialSlotDuration; - BookConfirm({required this.doctor, required this.selectedDate, required this.isLiveCareAppointment, required this.selectedTime, required this.initialSlotDuration}); + bool isWalkinAppointment = false; + + BookConfirm( + {required this.doctor, required this.selectedDate, required this.isLiveCareAppointment, required this.selectedTime, required this.initialSlotDuration, required this.isWalkinAppointment}); late DoctorsListService service; late PatientShareResponse patientShareResponse; @@ -62,6 +78,13 @@ class _BookConfirmState extends State { bool isEligible = false; bool isCash = false; + String? selectedPaymentMethod = ""; + String? selectedInstallments = ""; + String? tamaraPaymentStatus; + String? tamaraOrderID; + String? transID; + late MyInAppBrowser browser; + @override void initState() { // widget.authUser = new AuthenticatedUser(); @@ -212,13 +235,19 @@ class _BookConfirmState extends State { elevation: 0, onPressed: () async { bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; - if (isLiveCareSchedule) { - insertLiveCareScheduledAppointment(context, widget.doctor); + + if (widget.isWalkinAppointment) { + getWalkinAppointmentPatientShare(); } else { - insertAppointment(context, widget.doctor, widget.initialSlotDuration); + if (isLiveCareSchedule) { + insertLiveCareScheduledAppointment(context, widget.doctor); + } else { + checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!); + } } }, - child: Text(TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), + child: Text(widget.isWalkinAppointment ? TranslationBase.of(context).addToWaitingList : TranslationBase.of(context).bookAppo, + style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), ), ), ), @@ -226,6 +255,404 @@ class _BookConfirmState extends State { ); } + getWalkinAppointmentPatientShare() { + String errorMsg = ""; + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + GifLoaderDialogUtils.showMyDialog(context); + appo.doctorTitle = widget.doctor.doctorTitle; + appo.doctorNameObj = widget.doctor.name; + appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); + appo.projectName = widget.doctor.projectName; + + widget.service + .getPatientShareForWalkInAppointment( + widget.doctor.clinicID!, + widget.doctor.projectID!, + widget.doctor.doctorID!, + ) + .then((res) { + widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]); + GifLoaderDialogUtils.hideDialog(context); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + } + } else { + if (isInsured && isEligible) { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + } + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCashForWalkIn(widget.doctor.projectID!)}); + dialog.showAlertDialog(context); + } + } + + // widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]); + // GifLoaderDialogUtils.hideDialog(context); + // if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + // openPaymentDialog(appo, widget.patientShareResponse!); + // } else { + // insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + // } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) { + showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: PaymentDialog( + appo: appo, + patientShareResponse: patientShareResponse, + isCashPatient: isCash, + onPaymentMethodSelected: () {}, + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: false, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) { + print(value); + if (value != null) { + navigateToPaymentMethod(context, value as PatientShareResponse); + // projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo); + } else { + // projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); + } + }); + } + + Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.doctor.projectID; + appo.clinicID = widget.doctor.clinicID; + appo.clinicName = widget.doctor.clinicName; + appo.projectName = widget.doctor.projectName; + appo.appointmentNo = DateTime.now().millisecondsSinceEpoch; + appo.isLiveCareAppointment = false; + appo.doctorID = widget.doctor.doctorID; + appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); //widget.patientShareResponse.appointmentDate; + appo.serviceID = widget.patientShareResponse.serviceID; + + Navigator.push( + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + patientShare: widget.patientShareResponse.patientShareWithTax))) + .then((value) { + selectedPaymentMethod = value[0]; + if (value != null) { + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(appo, patientShareResponse); + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + projectViewModel.analytics.appointment.payment_method(appointment_type: 'Walk-In', clinic: widget.doctor.clinicName, payment_method: value[0], payment_type: 'appointment'); + } + }); + } + + void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async { + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value!; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = appo.clinicID; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = appo.doctorID; + applePayInsertRequest.projectID = appo.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = appo.appointmentDate; + applePayInsertRequest.appointmentNo = appo.appointmentNo; + applePayInsertRequest.orderDescription = "Appointment Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString(); + applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier!; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "Walk-In appointment payment", + orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + log("failureResult: ${failureResult.toString()}"); + AppToast.showErrorToast(message: failureResult.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + selectedPaymentMethod = paymentMethod[0]; + selectedInstallments = paymentMethod[1]; + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + browser.openPaymentBrowser( + amount, + "Walk-In appointment payment", + transID!, + appo.projectID.toString(), + authenticatedUser.emailAddress!, + paymentMethod[0]!, + authenticatedUser.patientType, + authenticatedUser.firstName!, + authenticatedUser.patientID, + authenticatedUser, + browser, + widget.patientShareResponse.isLiveCareAppointment!, + "2", + widget.patientShareResponse.isLiveCareAppointment! ? widget.patientShareResponse.clinicID.toString() : "", + context, + widget.patientShareResponse.appointmentDate, + widget.patientShareResponse.appointmentNo, + widget.patientShareResponse.clinicID, + widget.patientShareResponse.doctorID, + paymentMethod[1]); + // } + } + + onBrowserLoadStart(String url) { + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']; + tamaraOrderID = uri.queryParameters['orderId']; + } + } + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + try { + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID!, appo); + // if (tamaraPaymentStatus != null && tamaraPaymentStatus!.toLowerCase() == "approved") { + // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID!, num.parse(selectedInstallments!), appo); + // } else { + // updateTamaraRequestStatus( + // "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID! != null ? tamaraOrderID! : "", num.parse(selectedInstallments!), appo); + // } + } else { + checkPaymentStatus(appo); + } + } catch (err) { + print(err); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(selectedInstallments!), appo); + } else { + updateTamaraRequestStatus( + "Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(selectedInstallments!), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus!.toLowerCase() == "approved") { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, tamaraOrderID); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } + } + + addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + markAppointmentForTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) { + GifLoaderDialogUtils.hideDialog(context); + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appo.appointmentNo), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String txn_ref; + num amount; + String payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.checkPaymentStatus(transID!, false, context).then((res) { + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + txn_ref = res['Merchant_Reference']; + amount = res['Amount']; + payment_method = res['PaymentMethod']; + GifLoaderDialogUtils.hideDialog(context); + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, res); + projectViewModel.analytics.appointment.payment_success( + appointment_type: 'Walk-In', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.appointment.payment_fail( + appointment_type: 'Walk-In', + payment_method: selectedPaymentMethod, + clinic: appo.clinicName, + hospital: appo.projectName, + txn_amount: widget.patientShareResponse.patientShareWithTax.toString(), + txn_currency: currency, + error_type: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } + Widget showInfo(String title, String des) { return Container( child: Row( @@ -253,7 +680,7 @@ class _BookConfirmState extends State { ); } - cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) async { + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context, {int? invoiceNumber, int? lineItemNo, String? invoiceNoVP}) async { ConfirmDialog.closeAlertDialog(context); GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); DoctorsListService service = new DoctorsListService(); @@ -265,7 +692,7 @@ class _BookConfirmState extends State { if (isLiveCareSchedule != null && isLiveCareSchedule) { insertLiveCareScheduledAppointment(context, widget.doctor); } else { - insertAppointment(context, widget.doctor, widget.initialSlotDuration); + insertAppointment(context, widget.doctor, widget.initialSlotDuration, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo, invoiceNoVP: invoiceNoVP); } }); } else { @@ -290,7 +717,7 @@ class _BookConfirmState extends State { okText: "Update insurance", cancelText: "Continue as cash", okFunction: () => {openUpdateInsurance()}, - cancelFunction: () => {continueAsCash(docObject, appointmentNo)}); + cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)}); dialog.showAlertDialog(context); } }).catchError((err) { @@ -304,23 +731,172 @@ class _BookConfirmState extends State { Navigator.push(context, FadePage(page: InsuranceUpdate())); } - void continueAsCash(DoctorList docObject, String appointmentNo) { + void continueAsCash(DoctorList docObject, String appointmentNo, bool isLiveCareAppointment) { GifLoaderDialogUtils.showMyDialog(context); widget.service.convertPatientToCash(docObject.projectID!).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["MessageStatus"] == 1) { - getPatientShare(context, appointmentNo, docObject.clinicID!, docObject.projectID!, docObject); + if (isLiveCareAppointment) { + getLiveCareAppointmentPatientShare(context, appointmentNo, docObject!.clinicID!, docObject.projectID!, docObject); + } else { + getPatientShare(context, appointmentNo, docObject.clinicID!, docObject.projectID!, docObject); + } getToDoCount(); } else { AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + void continueAsCashForWalkIn(int projectID) { + GifLoaderDialogUtils.showMyDialog(context); + widget.service.convertPatientToCash(projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + getWalkinAppointmentPatientShare(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + insertWalkInAppointment(context, DoctorList docObject, int initialSlotDuration, paymentRes) async { + GifLoaderDialogUtils.showMyDialog( + context, + ); + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.doctorID = docObject.doctorID; + appo.clinicID = docObject.clinicID; + appo.projectID = docObject.projectID; + + widget.service + .insertWalkInAppointment( + docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context) + .then((res) { + if (res['MessageStatus'] == 1) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + appo.appointmentNo = res["AppointmentNo"]; // Add appointment No to the appointment project + Future.delayed(Duration(milliseconds: 500), () { + if (selectedPaymentMethod == "TAMARA") { + markAppointmentForTamara(appo); + addAdvancedNumberRequestTamara("Tamara-Advance-0000", paymentRes, res["AppointmentNo"].toString(), appo); + } else { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + createAdvancePayment(paymentRes, appo); + } else { + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(res["AppointmentNo"]), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + } + } + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog( + context, + ); + DoctorsListService service = new DoctorsListService(); + String paymentReference = res['Fort_id'].toString(); + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + addAdvancedNumberRequest( + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference, + appo.appointmentNo.toString(), + appo); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog( + context, + ); + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appointmentID), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + sendNfcCheckInRequest(String nfcId, int checkInBy, int appoNo, int projectID, int clinicID) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.sendCheckinNfcRequest(appoNo, nfcId, projectID, checkInBy, clinicID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(res["SuccessMsg"], this.context); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); + _showMyDialog(err, this.context); }); } - insertAppointment(context, DoctorList docObject, int initialSlotDuration) async { + checkPatientHasDermaPackage(DoctorList doctor, int patientID) { + GifLoaderDialogUtils.showMyDialog(context); + widget.service + .checkPatientHasDermaPackage( + patientID!, + doctor.clinicID!, + doctor.projectID!, + doctor.doctorID!, + projectViewModel.isArabic ? 1 : 2, + context, + ) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1 && res['PatientPackageComponent']['Message'] == 'Success') { + PatientPackageComponent package = PatientPackageComponent.fromJson(res['PatientPackageComponent']); + + ConfirmDialog dialog = ConfirmDialog( + context: context, + confirmMessage: "${TranslationBase.of(context).existingPackage} ${package.patientPackageComponents![0].procedureName}, ${TranslationBase.of(context).continueOrbookNew}", + okText: TranslationBase.of(context).proceedPackage, + cancelText: TranslationBase.of(context).newAppointment, + okFunction: () => { + ConfirmDialog.closeAlertDialog(context), + insertAppointment(context, widget.doctor, widget.initialSlotDuration, + invoiceNumber: package.patientPackageComponents![0].invoiceNo, + lineItemNo: package.patientPackageComponents![0].lineItemNo, + invoiceNoVP: package.patientPackageComponents![0].invoiceNo_VP.toString()) + }, + cancelFunction: () => {insertAppointment(context, widget.doctor, widget.initialSlotDuration)}, + ); + dialog.showAlertDialog(context); + } else { + insertAppointment(context, widget.doctor, widget.initialSlotDuration); + } + }).onError((error, stackTrace) { + insertAppointment(context, widget.doctor, widget.initialSlotDuration); + }); + } + + insertAppointment(context, DoctorList docObject, int initialSlotDuration, {int? invoiceNumber, int? lineItemNo, String? invoiceNoVP}) async { final timeSlot = DocAvailableAppointments.selectedAppoDateTime; String logs = await sharedPref.getString('selectedLogSlots'); List decodedLogs = json.decode(logs); @@ -329,7 +905,7 @@ class _BookConfirmState extends State { widget.service // .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, 'null', null, null, projectViewModel) .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context, - null, null, null, projectViewModel) + null, null, null, projectViewModel, invoiceNumber, lineItemNo, invoiceNoVP) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); @@ -366,14 +942,14 @@ class _BookConfirmState extends State { confirmMessage: res['ErrorEndUserMessage'], okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => {cancelAppointment(docObject, appo, context)}, + okFunction: () => {cancelAppointment(docObject, appo, context, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo)}, cancelFunction: () => {}, ); dialog.showAlertDialog(context); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err, localContext: context); }); projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); } @@ -476,7 +1052,7 @@ class _BookConfirmState extends State { okText: TranslationBase.of(context).updateInsuranceText, cancelText: TranslationBase.of(context).continueCash, okFunction: () => {openUpdateInsurance()}, - cancelFunction: () => {continueAsCash(docObject, appointmentNo)}); + cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)}); dialog.showAlertDialog(context); } } @@ -491,10 +1067,40 @@ class _BookConfirmState extends State { } getLiveCareAppointmentPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { + String errorMsg = ""; + widget.service.getLiveCareAppointmentPatientShare(appointmentNo, clinicID, projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { widget.patientShareResponse = new PatientShareResponse.fromJson(res); GifLoaderDialogUtils.hideDialog(context); - navigateToBookSuccess(context, docObject, widget.patientShareResponse, false); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && isEligible) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(docObject, appointmentNo, true)}); + dialog.showAlertDialog(context); + } + } + + // navigateToBookSuccess(context, docObject, widget.patientShareResponse, false); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -575,4 +1181,32 @@ class _BookConfirmState extends State { ), ); } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } } diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 9c448fd6..61bcb977 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -711,6 +711,7 @@ class _BookSuccessState extends State { payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); log("failureResult: ${failureResult.toString()}"); AppToast.showErrorToast(message: failureResult.toString()); }, diff --git a/lib/pages/BookAppointment/DentalComplaints.dart b/lib/pages/BookAppointment/DentalComplaints.dart index 7617f23a..44546b11 100644 --- a/lib/pages/BookAppointment/DentalComplaints.dart +++ b/lib/pages/BookAppointment/DentalComplaints.dart @@ -27,7 +27,7 @@ class DentalComplaints extends StatefulWidget { Function? onSelectedMethod; bool isDoctorNameSearch; - DentalComplaints({required this.searchInfo, this.onSelectedMethod, this.isDoctorNameSearch = false}); + DentalComplaints({required this.searchInfo, this.onSelectedMethod, this.isDoctorNameSearch = false}); @override _DentalComplaintsState createState() => _DentalComplaintsState(); @@ -243,8 +243,12 @@ class _DentalComplaintsState extends State { if (doctorByHospital.length != 0) { patientDoctorAppointmentListHospital[patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - patientDoctorAppointmentListHospital - .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.projectName, + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); } }); } else {} diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index f1738c85..77a7b74e 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -9,7 +9,10 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/LaserBooking.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LaserClinic.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; @@ -520,15 +523,9 @@ class _DoctorProfileState extends State with TickerProviderStateM // if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) { // navigateToDentalComplaints(context); // } else { - if (DocAvailableAppointments.areSlotsAvailable) { + if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) { if (projectViewModel.isLogin) { - if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) { - navigateToDentalComplaints(context); - } else { - final timeSlot = DocAvailableAppointments.selectedAppoDateTime; - navigateToBookConfirm(context); - projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); - } + canPayForWalkInAppointment(); } else { ConfirmDialog dialog = new ConfirmDialog( context: context, @@ -539,9 +536,43 @@ class _DoctorProfileState extends State with TickerProviderStateM cancelFunction: () => {}); dialog.showAlertDialog(context); } - } else - AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); - // } + } else { + if (DocAvailableAppointments.areSlotsAvailable) { + if (projectViewModel.isLogin) { + if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) { + navigateToDentalComplaints(context); + } else if (widget.isDoctorNameSearch && widget.doctor.clinicID == 253) { + navigateToLaserClinic(context); + } else { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + navigateToBookConfirm(context); + projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); + } + } else { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).loginToUseService, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {navigateToLogin()}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + } + + Future navigateToLaserClinic(BuildContext context) async { + HospitalsModel tempselectedHospital = new HospitalsModel(); + tempselectedHospital.iD = widget.doctor.projectID; + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: tempselectedHospital!), + ), + ); } Future navigateToDentalComplaints(BuildContext context) async { @@ -586,8 +617,33 @@ class _DoctorProfileState extends State with TickerProviderStateM selectedDate: DocAvailableAppointments.selectedDate!, selectedTime: DocAvailableAppointments.selectedTime!, initialSlotDuration: DocAvailableAppointments.initialSlotDuration!, + isWalkinAppointment: false, ), ), ); } + + Future navigateToWaitingAppointment(context) async { + projectViewModel.setWaitingAppointmentProjectID(widget.doctor.projectID!); + projectViewModel.setWaitingAppointmentDoctor(widget.doctor); + Navigator.push( + context, + FadePage( + page: WaitingAppointmentInfo(), + ), + ); + } + + canPayForWalkInAppointment() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.canPayForWalkInAppointment(widget.doctor.clinicID!, widget.doctor.projectID!, widget.doctor.doctorID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + navigateToWaitingAppointment(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); + print(err); + }); + } } diff --git a/lib/pages/BookAppointment/QRCode.dart b/lib/pages/BookAppointment/QRCode.dart index a96e8dc6..e27a55bb 100644 --- a/lib/pages/BookAppointment/QRCode.dart +++ b/lib/pages/BookAppointment/QRCode.dart @@ -387,7 +387,7 @@ class _QRCodeState extends State { DoctorsListService service = new DoctorsListService(); - service.sendCheckinNfcRequest(widget!.patientShareResponse!.appointmentNo!, nfcId, widget.patientShareResponse!.projectID!, checkInBy, context).then((res) { + service.sendCheckinNfcRequest(widget!.patientShareResponse!.appointmentNo!, nfcId, widget.patientShareResponse!.projectID!, checkInBy, widget.patientShareResponse!.clinicID!, context).then((res) { print(res); GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/BookAppointment/Search.dart b/lib/pages/BookAppointment/Search.dart index e391ca53..c7989cbf 100644 --- a/lib/pages/BookAppointment/Search.dart +++ b/lib/pages/BookAppointment/Search.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByDoctor.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/search_by_hospital_name.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -28,15 +29,20 @@ class _SearchState extends State with TickerProviderStateMixin { @override void initState() { - _tabController = new TabController(length: 2, vsync: this, initialIndex: widget.type); + _tabController = new TabController( + length: 3, + vsync: this, + initialIndex: widget.type, + ); super.initState(); } @override Widget build(BuildContext context) { AppGlobal.context = context; - ProjectViewModel projectViewModel = Provider.of(context); - GAnalytics.TREATMENT_TYPE = null; // reset treatment type on start new booking + // ProjectViewModel projectViewModel = Provider.of(context); + GAnalytics.TREATMENT_TYPE = + null; // reset treatment type on start new booking return AppScaffold( isShowAppBar: false, @@ -54,31 +60,58 @@ class _SearchState extends State with TickerProviderStateMixin { indicatorSize: TabBarIndicatorSize.tab, labelColor: Color(0xff2B353E), unselectedLabelColor: Color(0xff575757), - labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelPadding: + EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), labelStyle: TextStyle( - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontFamily: context.read().isArabic + ? 'Cairo' + : 'Poppins', fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: -0.48, ), unselectedLabelStyle: TextStyle( - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontFamily: context.read().isArabic + ? 'Cairo' + : 'Poppins', fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: -0.48, ), - tabs: [Text(TranslationBase.of(context).clinicName), Text(TranslationBase.of(context).doctorName)], + tabs: [ + Text( + TranslationBase.of(context).hospitalName, + style: TextStyle(fontSize: 12), + ), + Text( + TranslationBase.of(context).clinicName, + style: TextStyle(fontSize: 12), + ), + Text( + TranslationBase.of(context).doctorName, + style: TextStyle(fontSize: 12), + ) + ], onTap: (idx) { if (idx == 0) - projectViewModel.analytics.appointment.book_appointment_by_clinic(); + context + .read() + .analytics + .appointment + .book_appointment_by_clinic(); else - projectViewModel.analytics.appointment.book_appointment_by_doctor(); + context + .read() + .analytics + .appointment + .book_appointment_by_doctor(); }, ), Expanded( child: TabBarView( physics: NeverScrollableScrollPhysics(), children: [ + SearchByHospital(), SearchByClinic(clnicIds: widget.clnicIds), SearchByDoctor(), ], diff --git a/lib/pages/BookAppointment/SearchResults.dart b/lib/pages/BookAppointment/SearchResults.dart index 7d74702e..12cff848 100644 --- a/lib/pages/BookAppointment/SearchResults.dart +++ b/lib/pages/BookAppointment/SearchResults.dart @@ -10,27 +10,26 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class SearchResults extends StatefulWidget { +class SearchResults extends StatelessWidget { List doctorsList = []; List patientDoctorAppointmentListHospital; bool isLiveCareAppointment; bool isObGyneAppointment; bool isDoctorNameSearch; OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; - SearchResults({required this.doctorsList, required this.patientDoctorAppointmentListHospital, this.isObGyneAppointment = false, this.isDoctorNameSearch = false, required this.isLiveCareAppointment, this.obGyneProcedureListResponse}); - - @override - _SearchResultsState createState() => _SearchResultsState(); -} - -class _SearchResultsState extends State { - List tempList = []; - late ProjectViewModel projectViewModel; + SearchResults( + {required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse}); @override Widget build(BuildContext context) { - projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).bookAppo, isShowDecPage: false, @@ -38,44 +37,56 @@ class _SearchResultsState extends State { showNewAppBarTitle: true, showNewAppBar: true, backgroundColor: CustomColors.appBackgroudGrey2Color, - body: widget.patientDoctorAppointmentListHospital.isNotEmpty ? ListView.separated( - physics: BouncingScrollPhysics(), - separatorBuilder: (context, index) { - return Container( - height: 12, - margin: EdgeInsets.only(left: 21, right: 21), - ); - }, - itemBuilder: (context, index) { - return AppExpandableNotifier( - title: (widget.patientDoctorAppointmentListHospital[index].distanceInKMs != "0") - ? widget.patientDoctorAppointmentListHospital[index].filterName! + " - " + widget.patientDoctorAppointmentListHospital[index].distanceInKMs! + " " + TranslationBase.of(context).km - : widget.patientDoctorAppointmentListHospital[index].filterName, - isTitleSingleLine: false, - isExpand: widget.patientDoctorAppointmentListHospital.length == 1 ? true : false, - bodyWidget: ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), - itemBuilder: (context, _index) { - final doctor = widget.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList![_index]; - return DoctorView( - doctor: doctor, - isLiveCareAppointment: widget.isLiveCareAppointment, - isObGyneAppointment: widget.isObGyneAppointment, - isDoctorNameSearch: widget.isDoctorNameSearch, - obGyneProcedureListResponse: widget.obGyneProcedureListResponse, - isShowDate: false, - onTap: () { - projectViewModel.analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); - }); - }, - separatorBuilder: (context, index) => SizedBox(height: 14), - itemCount: widget.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.length), - ); - }, - itemCount: widget.patientDoctorAppointmentListHospital.length, - ) : getNoDataWidget(context), + body: patientDoctorAppointmentListHospital.isNotEmpty + ? ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + title: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + ? patientDoctorAppointmentListHospital[index].filterName! + " - " + patientDoctorAppointmentListHospital[index].distanceInKMs! + " " + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital[index].filterName, + projectTitleTop: patientDoctorAppointmentListHospital[index].projectTopName, + projectTitleBottom: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + ? patientDoctorAppointmentListHospital[index].projectBottomName.toString() + + " - " + + patientDoctorAppointmentListHospital[index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital[index].projectBottomName.toString(), + isTitleSingleLine: false, + isDoctorSearchResult: isDoctorSearchResult, + isExpand: patientDoctorAppointmentListHospital.length == 1 ? true : false, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + itemBuilder: (context, _index) { + final doctor = patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList![_index]; + return DoctorView( + doctor: doctor, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + obGyneProcedureListResponse: obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context.read().analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); + }); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.length), + ); + }, + itemCount: patientDoctorAppointmentListHospital.length, + ) + : getNoDataWidget(context), ); } } diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index a2940ce8..6e12c68e 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -60,6 +60,8 @@ class _DocAvailableAppointmentsState extends State wit var language; bool isLiveCareSchedule = false; + bool isWaitingAppointmentAvailable = false; + // String selectedLogSlots =''; @override @@ -198,7 +200,7 @@ class _DocAvailableAppointmentsState extends State wit _events.forEach((key, value) { final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime endTime = startTime.add(const Duration(hours: 2)); - meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); }); return meetings; } @@ -206,7 +208,9 @@ class _DocAvailableAppointmentsState extends State wit openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { dayEvents.clear(); DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); - + if (isWaitingAppointmentAvailable && DateUtils.isSameDay(dateStart, DateTime.now())) { + dayEvents.add(TimeSlot(isoTime: TranslationBase.of(context).waitingAppointment, start: DateTime.now(), end: DateTime.now(), vidaDate: "")); + } freeSlots.forEach((v) { if (v.start == dateStartObj) dayEvents.add(v); }); @@ -276,23 +280,27 @@ class _DocAvailableAppointmentsState extends State wit selectedDateJSON = freeSlotsResponse[0]; }); openTimeSlotsPickerForDate( - (isLiveCareSchedule != null && isLiveCareSchedule) + isWaitingAppointmentAvailable + ? DateTime.now() + : (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(selectedDateJSON) + : DateUtil.convertStringToDateSaudiTimezone( + selectedDateJSON, + int.parse( + widget.doctor.projectID.toString(), + ), + ), + docFreeSlots); + _calendarController.selectedDate = isWaitingAppointmentAvailable + ? DateTime.now() + : (isLiveCareSchedule != null && isLiveCareSchedule) ? DateUtil.convertStringToDate(selectedDateJSON) : DateUtil.convertStringToDateSaudiTimezone( selectedDateJSON, int.parse( widget.doctor.projectID.toString(), ), - ), - docFreeSlots); - _calendarController.selectedDate = (isLiveCareSchedule != null && isLiveCareSchedule) - ? DateUtil.convertStringToDate(selectedDateJSON) - : DateUtil.convertStringToDateSaudiTimezone( - selectedDateJSON, - int.parse( - widget.doctor.projectID.toString(), - ), - ); + ); _calendarController.displayDate = _calendarController.selectedDate; return _eventsParsed; } @@ -323,10 +331,10 @@ class _DocAvailableAppointmentsState extends State wit Widget getSelectedButton(int index) { return CustomTextButton( - backgroundColor: CustomColors.green, + backgroundColor: dayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, elevation: 0, side: BorderSide( - color: CustomColors.green, //Color of the border + color: dayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, //Color of the border style: BorderStyle.solid, //Style of the border width: 1.5 //width of the border ), @@ -349,21 +357,23 @@ class _DocAvailableAppointmentsState extends State wit GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { + isWaitingAppointmentAvailable = res['IsAllowToBookWaitingAppointment']; // true; + // isWaitingAppointmentAvailable = true; // true; DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['FreeTimeSlots']; _getJSONSlots().then((value) { - setState(() => { - _events.clear(), - _events = value, - if (widget.doctorSchedule != null) - { - _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])), - _calendarController.selectedDate = DateUtil.convertStringToDate( - widget.doctorSchedule['Date'], - ) - } - }); + setState(() { + _events.clear(); + _events = value; + if (widget.doctorSchedule != null) { + _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])); + _calendarController.selectedDate = DateUtil.convertStringToDate( + widget.doctorSchedule['Date'], + ); + } + ; + }); }); } else { DocAvailableAppointments.areAppointmentsAvailable = false; @@ -464,11 +474,12 @@ class MeetingDataSource extends CalendarDataSource { } class Meeting { - Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); String eventName; DateTime from; DateTime to; Color background; bool isAllDay; + String notes; } diff --git a/lib/pages/BookAppointment/components/LaserClinic.dart b/lib/pages/BookAppointment/components/LaserClinic.dart index 17c63b09..a4fc5117 100644 --- a/lib/pages/BookAppointment/components/LaserClinic.dart +++ b/lib/pages/BookAppointment/components/LaserClinic.dart @@ -211,7 +211,7 @@ class _LaserClinicState extends State with SingleTickerProviderStat List arrDistance = []; List result; int numAll; - List _patientDoctorAppointmentListHospital =[]; + List _patientDoctorAppointmentListHospital = []; DoctorsListService service = new DoctorsListService(); projectViewModel.selectedBodyPartList = _selectedBodyPartList; @@ -234,8 +234,12 @@ class _LaserClinicState extends State with SingleTickerProviderStat if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital - .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.projectName, + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); } }); } else {} @@ -256,7 +260,7 @@ class _LaserClinicState extends State with SingleTickerProviderStat } Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: true,))) .then((value) { setState(() { // dropdownValue = null; diff --git a/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart b/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart index 7901d7b6..3a3f8270 100644 --- a/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart +++ b/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart @@ -69,7 +69,7 @@ class _LiveCareBookAppointmentState extends State { width: 150.0), ), Container( - margin: EdgeInsets.only(left: 10.0, right: 10.0), + margin: EdgeInsets.only(left: 10.0, right: 8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 6fb76141..158f2c49 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -1,6 +1,9 @@ import "dart:collection"; +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; @@ -60,7 +63,6 @@ class _SearchByClinicState extends State { final GlobalKey clinicDropdownKey = GlobalKey(); final GlobalKey projectDropdownKey = GlobalKey(); TextEditingController ageController = new TextEditingController(); - late ProjectViewModel projectViewModel; String radioValue = ""; @@ -70,15 +72,14 @@ class _SearchByClinicState extends State { void initState() { locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); WidgetsBinding.instance.addPostFrameCallback((_) => getClinicsList()); + checkPVM(); super.initState(); } - @override - Widget build(BuildContext context) { - projectViewModel = Provider.of(context); - if (projectViewModel.isLogin) { + void checkPVM() { + if (context.read().isLogin) { if (radioValue == null) { - if (projectViewModel.user.gender == 1) { + if (context.read().user.gender == 1) { radioValue = TranslationBase.of(context).male; } else { radioValue = TranslationBase.of(context).female; @@ -88,16 +89,20 @@ class _SearchByClinicState extends State { radioValue = TranslationBase.of(context).female; } if (ageController.text.isEmpty) { - ageController.text = projectViewModel.isLogin ? projectViewModel.user!.age.toString() : ""; + ageController.text = context.read().isLogin ? context.read().user!.age.toString() : ""; ageController.selection = TextSelection.fromPosition(TextPosition(offset: ageController.text.length)); } + } + @override + Widget build(BuildContext context) { + AppGlobal.context = context; return Container( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (projectViewModel.isLogin) + if (context.read().isLogin) Column( children: [ Padding( @@ -207,7 +212,18 @@ class _SearchByClinicState extends State { }); }, ), - Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), + AutoSizeText( + TranslationBase.of(context).nearestAppo.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), ], ), ), @@ -246,7 +262,7 @@ class _SearchByClinicState extends State { if (!nearestAppo) getDoctorsList(context); } else {} }); - projectViewModel.analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); + context.read().analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); }); }, child: Container( @@ -325,7 +341,18 @@ class _SearchByClinicState extends State { items: projectsList.map((HospitalsModel item) { return DropdownMenuItem( value: item, - child: Text('${item.name!}'), + child: AutoSizeText( + item.name!, + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text('${item.name!}'), ); }).toList(), onChanged: (HospitalsModel? newValue) async { @@ -527,7 +554,7 @@ class _SearchByClinicState extends State { } getProjectsList() { - int languageID = projectViewModel.isArabic ? 1 : 2; + int languageID = context.read().isArabic ? 1 : 2; ClinicListService service = new ClinicListService(); List projectsListLocal = []; service @@ -563,8 +590,8 @@ class _SearchByClinicState extends State { searchInfo.clinic = selectedClinic; searchInfo.date = DateTime.now(); - if (projectViewModel.isLogin) { - if (projectViewModel.user.age! > 12) { + if (context.read().isLogin) { + if (context.read().user.age! > 12) { navigateToDentalComplaints(context, searchInfo); } else { callDoctorsSearchAPI(17); @@ -601,7 +628,7 @@ class _SearchByClinicState extends State { } callDoctorsSearchAPI(int clinicID) { - int languageID = projectViewModel.isArabic ? 1 : 2; + int languageID = context.read().isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); List doctorsList = []; List arr = []; @@ -623,15 +650,19 @@ class _SearchByClinicState extends State { doctorsList.forEach((element) { List doctorByHospital = _patientDoctorAppointmentListHospital .where( - (elementClinic) => elementClinic.filterName == element.projectName, + (elementClinic) => elementClinic.filterName == element.getProjectCompleteName(), ) .toList(); if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital - .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.getProjectCompleteName(), + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName ?? "", + projectBottomName: element.projectBottomName ?? "", + patientDoctorAppointment: element)); } }); } else {} @@ -648,7 +679,7 @@ class _SearchByClinicState extends State { }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err, localContext: context); }); } @@ -680,7 +711,7 @@ class _SearchByClinicState extends State { Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { isProjectLoaded = false; - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: true,))) .then((value) { setState(() { dropdownValue = "null"; diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index be4c8c81..7c093958 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -20,7 +20,6 @@ class SearchByDoctor extends StatefulWidget { class _SearchByDoctorState extends State { TextEditingController doctorNameController = new TextEditingController(); late bool _isButtonDisabled; - late ProjectViewModel projectViewModel; @override void initState() { @@ -30,7 +29,6 @@ class _SearchByDoctorState extends State { @override Widget build(BuildContext context) { - projectViewModel = Provider.of(context); return Column( children: [ Expanded( @@ -90,12 +88,12 @@ class _SearchByDoctorState extends State { } getDoctorsList(BuildContext context) { - int languageID = projectViewModel.isArabic ? 1 : 2; + int languageID = context.read().isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); List doctorsList = []; DoctorsListService service = new DoctorsListService(); - List _patientDoctorAppointmentListHospital =[]; + List _patientDoctorAppointmentListHospital = []; service.getDoctorsListByName(doctorNameController.text, languageID, context).then((res) { // GifLoaderDialogUtils.hideDialog(context); @@ -107,13 +105,18 @@ class _SearchByDoctorState extends State { }); doctorsList.forEach((element) { - List doctorByHospital = _patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.projectName).toList(); + List doctorByHospital = + _patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.getProjectCompleteName()).toList(); if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital - .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.getProjectCompleteName(), + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); } }); } else { @@ -150,11 +153,12 @@ class _SearchByDoctorState extends State { _searchDoctor(BuildContext context) { getDoctorsList(context); - projectViewModel.analytics.appointment.book_appointment_doctor_search(query: doctorNameController.text); + context.read().analytics.appointment.book_appointment_doctor_search(query: doctorNameController.text); } navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) { - Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, isDoctorNameSearch: true, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))); + Navigator.push(context, + FadePage(page: SearchResults(isLiveCareAppointment: false, isDoctorNameSearch: true, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: true,))); } Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) { diff --git a/lib/pages/BookAppointment/components/search_by_hospital_name.dart b/lib/pages/BookAppointment/components/search_by_hospital_name.dart new file mode 100644 index 00000000..34b82512 --- /dev/null +++ b/lib/pages/BookAppointment/components/search_by_hospital_name.dart @@ -0,0 +1,507 @@ +import 'dart:collection'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LaserClinic.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../../config/shared_pref_kay.dart'; +import '../../../config/size_config.dart'; +import '../../../core/model/hospitals/hospitals_model.dart'; +import '../../../core/viewModels/project_view_model.dart'; +import '../../../models/Appointments/DoctorListResponse.dart'; +import '../../../models/Appointments/SearchInfoModel.dart'; +import '../../../models/Clinics/ClinicListResponse.dart'; +import '../../../services/appointment_services/GetDoctorsList.dart'; +import '../../../services/authentication/auth_provider.dart'; +import '../../../services/clinic_services/get_clinic_service.dart'; +import '../../../uitl/app_toast.dart'; +import '../../../uitl/gif_loader_dialog_utils.dart'; +import '../../../uitl/translations_delegate_base.dart'; +import '../../../widgets/transitions/fade_page.dart'; +import '../../livecare/livecare_home.dart'; +import '../DentalComplaints.dart'; +import '../LaserBooking.dart'; +import '../SearchResults.dart'; +import '../dialog/clinic_list_dialog.dart'; +import 'LiveCareBookAppointment.dart'; + +class SearchByHospital extends StatefulWidget { + @override + State createState() => _SearchByHospitalState(); +} + +class _SearchByHospitalState extends State { + HospitalsModel? selectedHospital; + bool nearestAppo = false; + + String? selectedClinicName; + List projectsList = []; + List? clinicIds = List.empty(); + + final GlobalKey projectDropdownKey = GlobalKey(); + + List clinicsList = []; + bool isMobileAppDentalAllow = false; + ListClinicCentralized? selectedClinic; + + String? dropdownValue; + String dropdownTitle = ""; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) => getProjectsList()); + } + + @override + Widget build(BuildContext context) { + AppGlobal.context = context; + + return Column( + children: [ + Padding( + padding: const EdgeInsets.only(left: 6, right: 6, top: 16), + child: Row( + children: [ + Checkbox( + activeColor: CustomColors.accentColor, + value: nearestAppo, + onChanged: (bool? value) { + nearestAppo = value ?? false; + setState(() {}); + }, + ), + AutoSizeText( + TranslationBase.of(context).nearestAppo.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), + ], + ), + ), + mHeight(8), + InkWell( + onTap: () { + openDropdown(projectDropdownKey); + }, + child: Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(left: 20, right: 20), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectHospital, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + width: double.infinity, + child: DropdownButtonHideUnderline( + child: DropdownButton( + key: projectDropdownKey, + hint: Text(TranslationBase.of(context).selectHospital), + value: selectedHospital, + iconSize: 0, + isExpanded: true, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + items: projectsList.map((HospitalsModel item) { + return DropdownMenuItem( + value: item, + child: AutoSizeText( + item.name!, + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text('${item.name!}'), + ); + }).toList(), + onChanged: (HospitalsModel? newValue) { + getClinicWrtHospital(newValue); + setState(() { + selectedHospital = newValue; + }); + }, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + )), + ), + if (clinicIds?.isNotEmpty == true) ...[ + mHeight(8), + InkWell( + onTap: () { + showClickListDialog(context, clinicIds ?? List.empty(), onSelection: (ListClinicCentralized clincs) { + selectedClinic = clincs; + Navigator.pop(context); + setState(() { + dropdownTitle = clincs.clinicDescription!; + dropdownValue = clincs.clinicID.toString() + "-" + clincs.isLiveCareClinicAndOnline.toString() + "-" + clincs.liveCareClinicID.toString() + "-" + clincs.liveCareServiceID.toString(); + }); + getDoctorsList(context); + + context.read().analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); + }); + }, + child: Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(left: 20, right: 20), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 8), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectClinic, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 2), + child: Text( + dropdownTitle, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + ), + ), + ) + ] + ], + ); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + GestureDetector? searchForGestureDetector(BuildContext element) { + GestureDetector? detector; + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + }); + return detector; + } + + getProjectsList() { + GifLoaderDialogUtils.showMyDialog(context); + + int languageID = context.read().isArabic ? 1 : 2; + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + } else {} + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + + print(err); + }); + } + + void getClinicWrtHospital(HospitalsModel? newValue) async { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + setState(() { + clinicIds = List.empty(); + }); + List clinicId = []; + try { + Map res = await service.getClinicByHospital(projectID: newValue?.mainProjectID.toString() ?? ""); + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + List list = res['ListClinic']; + + if (list.isEmpty) { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + res['ListClinic'].forEach((v) { + clinicId.add(ListClinicCentralized.fromJson(v)); + }); + clinicIds = clinicId; + setState(() {}); + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + } catch (e) { + print("the error is $e"); + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + GifLoaderDialogUtils.hideDialog(context); + } + + // .then((res) { + // print("the result is obtained"); + // GifLoaderDialogUtils.hideDialog(context); + // if (res['MessageStatus'] == 1) { + // List list = res['ListClinic']; + // + // if(list.isEmpty){ + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // + // } + // res['ListClinic'].forEach((v) { + // clinicId?.add(ListClinicCentralized.fromJson(v)); + // }); + // clinicIds = clinicId; + // setState(() { + // + // }); + // } else { + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // } + // }).catchError((err) { + // print('the error is $err'); + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // GifLoaderDialogUtils.hideDialog(context); + // }).catchError((err) { + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // GifLoaderDialogUtils.hideDialog(context); + // + // print(err); + // }); + } + + @override + void dispose() { + super.dispose(); + } + + Future navigateToDentalComplaints(BuildContext context, SearchInfo searchInfo) async { + Navigator.push( + context, + FadePage( + page: DentalComplaints(searchInfo: searchInfo), + ), + ).then((value) { + setState(() { + dropdownValue = null; + selectedHospital = null; + dropdownTitle = ""; + clinicIds = List.empty(); + }); + }); + } + + callDoctorsSearchAPI(int clinicID) { + int languageID = context.read().isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + service.getDoctorsList(clinicID, selectedHospital?.mainProjectID.toString() != "" ? int.parse(selectedHospital?.mainProjectID.toString() ?? "-1") : 0, nearestAppo, languageID, null).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + if (res['DoctorList'].length != 0) { + doctorsList.clear(); + res['DoctorList'].forEach((v) { + doctorsList.add(DoctorList.fromJson(v)); + }); + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.getProjectCompleteName(), + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); + } else { + _patientDoctorAppointmentListHospital + .add(PatientDoctorAppointmentList(filterName: element.getProjectCompleteName(), distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + } + }); + } else {} + }); + + result = LinkedHashSet.from(arr).toList(); + numAll = result.length; + navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err, localContext: context); + }); + } + + Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { + Navigator.push(context, + FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, isDoctorSearchResult: false, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + .then((value) { + print("navigation return "); + dropdownValue = null; + dropdownTitle = ""; + selectedHospital = null; + clinicIds = List.empty(); + setState(() {}); + // getProjectsList(); + }); + } + + Future navigateToLaserClinic(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: selectedHospital!), + ), + ).then((value) { + print("LaserBooking navigation return "); + setState(() { + dropdownValue = null; + selectedHospital = null; + dropdownTitle = ""; + clinicIds = List.empty(); + }); + }); + } + + getDoctorsList(BuildContext context) { + SearchInfo searchInfo = new SearchInfo(); + if (dropdownValue != null) if (dropdownValue!.split("-")[0] == "17") { + searchInfo.ProjectID = int.parse(selectedHospital?.mainProjectID.toString() ?? ""); + searchInfo.ClinicID = int.parse(dropdownValue!.split("-")[0]); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; + searchInfo.date = DateTime.now(); + + if (context.read().isLogin) { + if (context.read().user.age! > 12) { + navigateToDentalComplaints(context, searchInfo); + } else { + callDoctorsSearchAPI(17); + } + } else { + navigateToDentalComplaints(context, searchInfo); + } + } else if (dropdownValue!.split("-")[0] == "253") { + navigateToLaserClinic(context); + // callDoctorsSearchAPI(); + } else if (dropdownValue!.split("-")[1] == "true" + // && authProvider.isLogin && + // authUser.patientType == 1 + ) { + Navigator.push( + context, + FadePage( + page: LiveCareBookAppointment(clinicName: dropdownTitle, liveCareClinicID: dropdownValue!.split("-")[2], liveCareServiceID: dropdownValue!.split("-")[3]), + ), + ).then((value) { + print("navigation return "); + if (value == "false") dropdownValue = null; + + // setState(() { + // }); + if (value == "livecare") { + Navigator.push(context, FadePage(page: LiveCareHome())); + } + if (value == "schedule") { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + }); + setState(() {}); + } else { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + } +} diff --git a/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart b/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart index c68db13a..c3d82c74 100644 --- a/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart +++ b/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart @@ -1,4 +1,7 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -79,7 +82,7 @@ class _ClickListDialogState extends State { }, decoration: InputDecoration( hintStyle: TextStyle(fontSize: 17), - hintText: 'Search Clinic', + hintText: TranslationBase.of(context).searchClinic, suffixIcon: Icon(Icons.search), border: InputBorder.none, contentPadding: EdgeInsets.all(12), @@ -99,8 +102,20 @@ class _ClickListDialogState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded(child: Text(tempClinicsList[index].clinicDescription!.trim())), - tempClinicsList[index].isLiveCareClinicAndOnline! + Expanded( + child: AutoSizeText( + tempClinicsList[index].clinicDescription!.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + ), + tempClinicsList[index].isLiveCareClinicAndOnline == true ? SvgPicture.asset( 'assets/images/new-design/video_icon_green_right.svg', height: 12, diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart new file mode 100644 index 00000000..f1f8d934 --- /dev/null +++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart @@ -0,0 +1,113 @@ +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class WaitingAppointmentInfo extends StatelessWidget { + const WaitingAppointmentInfo({super.key}); + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).waitingAppointment, + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + "assets/images/new/waitingAppo.svg", + width: 52.0, + height: 52.0, + ), + mHeight(11), + Text( + TranslationBase.of(context).whatWaitingAppointment, + maxLines: 1, + style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(11), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Text( + TranslationBase.of(context).waitingAppointmentText1, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + mHeight(18), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Text( + TranslationBase.of(context).waitingAppointmentText2, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + mHeight(24), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.warning, + size: 20, + color: Color(0xffA78618), + ), + mWidth(10), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + TranslationBase.of(context).waitingAppointmentText3, + style: TextStyle( + fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w600, color: Color(0xffA78618), letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: 80, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: Container( + child: DefaultButton( + TranslationBase.of(context).continues, + () { + Navigator.push( + context, + FadePage( + page: WaitingAppointmentVerification(), + ), + ); + }, + color: CustomColors.accentColor, + ), + ), + ), + ); + } +} diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart new file mode 100644 index 00000000..6853c6d9 --- /dev/null +++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart @@ -0,0 +1,292 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +import '../../../uitl/utils.dart'; + +class WaitingAppointmentVerification extends StatefulWidget { + const WaitingAppointmentVerification({super.key}); + + @override + State createState() => _WaitingAppointmentVerificationState(); +} + +class _WaitingAppointmentVerificationState extends State { + String selectedVerificationMethod = "QR"; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).waitingAppointment, + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(11), + Text( + TranslationBase.of(context).waitingAppointmentVerificationMethod, + maxLines: 1, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24), + ), + mHeight(12), + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "QR"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "QR" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/qr_code.svg", + ), + ), + Text( + TranslationBase.of(context).pharmaLiveCareScanQR, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + Divider(), + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "NFC"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "NFC" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/contactless.svg", + ), + ), + Text( + TranslationBase.of(context).scanNFC, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + Divider(), + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "Location"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "Location" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/location.svg", + ), + ), + Text( + TranslationBase.of(context).checkInViaLocation, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + mHeight(6), + ], + ), + ), + ), + mHeight(12), + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(12), + Text( + TranslationBase.of(context).howToUseVerificationMethod, + maxLines: 1, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24), + ), + mHeight(12), + Image.asset( + 'assets/images/new/NFCCheckIn_QR_gps_HMG.png', + fit: BoxFit.fitWidth, + width: MediaQuery.of(context).size.width, + ), + mHeight(12), + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: 80, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: Container( + child: DefaultButton( + TranslationBase.of(context).continues, + () { + startVerification(); + }, + color: CustomColors.accentColor, + ), + ), + ), + ); + } + + startVerification() { + switch (selectedVerificationMethod) { + case "QR": + startQRCodeScan(); + break; + case "NFC": + startNFCScan(); + break; + case "Location": + startLocationCheckIn(); + break; + } + } + + checkScannedNFCAndQRCode(String nfcId) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.checkScannedNFCAndQRCode(nfcId, projectViewModel.waitingAppointmentDoctor!.projectID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + projectViewModel.setWaitingAppointmentNFCCode(nfcId); + if (res["returnValue"] == 1) { + navigateToBookConfirm(context); + } else { + AppToast.showErrorToast(message: "Invalid verification point scanned."); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + Future navigateToBookConfirm(context) async { + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + Navigator.push( + context, + FadePage( + page: BookConfirm( + doctor: projectViewModel.waitingAppointmentDoctor!, + isLiveCareAppointment: false, + selectedDate: formatter.format(DateTime.now()), + selectedTime: TranslationBase.of(context).waitingAppointment, + initialSlotDuration: 15, + isWalkinAppointment: true, + ), + ), + ); + } + + startLocationCheckIn() async { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, projectViewModel.waitingAppointmentProjectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + projectViewModel.setWaitingAppointmentNFCCode(projectDetailListModel.checkInQrCode!); + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + navigateToBookConfirm(context); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + + startNFCScan() { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + checkScannedNFCAndQRCode(nfcId); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + // locator().todoList.to_do_list_nfc_cancel(widget.appointment!); + }); + }); + } + + startQRCodeScan() async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + checkScannedNFCAndQRCode(onlineCheckInQRCode); + } else {} + } +} diff --git a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart index 765e83fa..8f18a016 100644 --- a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart +++ b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart @@ -64,7 +64,7 @@ class _DentalComplaintCardState extends State { getChiefComplaintsList() { int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; List doctorsList = []; - List _patientDoctorAppointmentListHospital =[]; + List _patientDoctorAppointmentListHospital = []; GifLoaderDialogUtils.showMyDialog(context); ClinicListService service = new ClinicListService(); @@ -88,8 +88,12 @@ class _DentalComplaintCardState extends State { if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital - .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.projectName, + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); } }); navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); @@ -104,6 +108,6 @@ class _DentalComplaintCardState extends State { } Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { - Navigator.push(context, FadePage(page: SearchResults(doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isLiveCareAppointment: false))); + Navigator.push(context, FadePage(page: SearchResults(doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isLiveCareAppointment: false, isDoctorSearchResult: true,))); } } diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index d186c953..3e27f9ba 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -23,7 +23,7 @@ import 'package:provider/provider.dart'; import '../DoctorProfile.dart'; -class DoctorView extends StatelessWidget { +class DoctorView extends StatefulWidget { final DoctorList doctor; bool? isLiveCareAppointment; bool isObGyneAppointment; @@ -36,7 +36,7 @@ class DoctorView extends StatelessWidget { DoctorView( {required this.doctor, - this.isLiveCareAppointment, + this.isLiveCareAppointment, this.isObGyneAppointment = false, this.isDoctorNameSearch = false, this.isContinueDentalPlan = false, @@ -45,23 +45,29 @@ class DoctorView extends StatelessWidget { this.onTap, this.obGyneProcedureListResponse}); + @override + State createState() => _DoctorViewState(); +} + +class _DoctorViewState extends State with AutomaticKeepAliveClientMixin { late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); + super.build(context); return InkWell( onTap: () { - if (isObGyneAppointment) { + if (widget.isObGyneAppointment) { next(context); } else { // if (doctor.clinicID == 17 && isDoctorNameSearch) { // showDentalChiefComplaintsList(context); // } else - if (isShowFlag) { - getDoctorsProfile(context, doctor, isAppo: true, isContinueDentalPlan: isContinueDentalPlan); + if (widget.isShowFlag) { + getDoctorsProfile(context, widget.doctor, isAppo: true, isContinueDentalPlan: widget.isContinueDentalPlan); } - (onTap ?? () {})(); // For log analytics of doctor click from book appointment + (widget.onTap ?? () {})(); // For log analytics of doctor click from book appointment } }, child: Container( @@ -88,23 +94,25 @@ class DoctorView extends StatelessWidget { children: [ Expanded( child: Text( - doctor.name ?? "", + widget.doctor.name ?? "", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), ), ), - isShowDate ? Text( - DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(doctor.date)), - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12), - ) : Container(), + widget.isShowDate + ? Text( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.doctor.date)), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12), + ) + : Container(), ], ), - if (doctor.doctorTitle != null) SizedBox(height: 6), + if (widget.doctor.doctorTitle != null) SizedBox(height: 6), Row( mainAxisSize: MainAxisSize.min, children: [ LargeAvatar( - name: doctor.name ?? "", - url: doctor.doctorImageURL!, + name: widget.doctor.name ?? "", + url: widget.doctor.doctorImageURL!, width: 48, height: 48, ), @@ -114,17 +122,25 @@ class DoctorView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (doctor.clinicName != null) MyRichText(TranslationBase.of(context).clinic + ":", doctor.clinicName!, projectViewModel.isArabic), - if (doctor.projectName != null) MyRichText(TranslationBase.of(context).branch, doctor.projectName!, projectViewModel.isArabic), - if (doctor.speciality != null && doctor.speciality!.length > 0) - Text( - this.doctor.speciality![0].trim(), - // getDoctorSpeciality(this.doctor.speciality).trim(), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), - ), - if (doctor.nearestFreeSlot != null) + if (widget.doctor.clinicName != null) MyRichText(TranslationBase.of(context).clinic + ":", widget.doctor.clinicName!, context.read().isArabic), + if (widget.doctor.projectName != null) MyRichText(TranslationBase.of(context).branch, widget.doctor.projectName!, context.read().isArabic), + if (!projectViewModel.isArabic) + if (widget.doctor.speciality != null && widget.doctor.speciality!.length > 0) + Text( + this.widget.doctor.speciality![0].trim(), + // getDoctorSpeciality(this.doctor.speciality).trim(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), + ), + if (projectViewModel.isArabic) + if (widget.doctor.specialityN != null && widget.doctor.specialityN!.length > 0) + Text( + this.widget.doctor.specialityN![0].trim(), + // getDoctorSpeciality(this.doctor.speciality).trim(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), + ), + if (widget.doctor.nearestFreeSlot != null) Text( - getDate(doctor.nearestFreeSlot), + getDate(widget.doctor.nearestFreeSlot), style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff359846), letterSpacing: -0.48, height: 18 / 12), ), Row( @@ -140,9 +156,18 @@ class DoctorView extends StatelessWidget { itemSize: 20, ignoreGestures: true, ratingWidget: RatingWidget( - full: Icon(Icons.star, color: CustomColors.accentColor,), - half: Icon(Icons.star_half, color: CustomColors.accentColor,), - empty: Icon(Icons.star, color: CustomColors.accentColor,), + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), ), tapOnlyMode: true, itemPadding: EdgeInsets.symmetric(horizontal: 4.0), @@ -161,7 +186,7 @@ class DoctorView extends StatelessWidget { // filledIcon: Icons.star, // emptyIcon: Icons.star_border, // ), - if (isShowFlag) + if (widget.isShowFlag) Icon( Icons.arrow_forward, color: Theme.of(context).primaryColor, @@ -183,13 +208,13 @@ class DoctorView extends StatelessWidget { showDentalChiefComplaintsList(BuildContext context) { HospitalsModel selectedHospital = new HospitalsModel(); - selectedHospital.name = doctor.projectName; + selectedHospital.name = widget.doctor.projectName; ListClinicCentralized selectedClinic = new ListClinicCentralized(); - selectedClinic.clinicDescription = doctor.clinicName; + selectedClinic.clinicDescription = widget.doctor.clinicName; SearchInfo searchInfo = new SearchInfo(); - searchInfo.ProjectID = doctor.projectID; - searchInfo.ClinicID = doctor.clinicID; + searchInfo.ProjectID = widget.doctor.projectID; + searchInfo.ClinicID = widget.doctor.clinicID; searchInfo.date = DateTime.now(); searchInfo.hospital = selectedHospital; searchInfo.clinic = selectedClinic; @@ -260,8 +285,14 @@ class DoctorView extends StatelessWidget { } void next(BuildContext context) { - Navigator.push(context, - FadePage(page: ObGyneTimeSlots(projectID: doctor.projectID!, selectedClinicID: doctor.clinicID!, selectedDoctorID: doctor.doctorID!, obGyneProcedureListResponse: obGyneProcedureListResponse!))); + Navigator.push( + context, + FadePage( + page: ObGyneTimeSlots( + projectID: widget.doctor.projectID!, + selectedClinicID: widget.doctor.clinicID!, + selectedDoctorID: widget.doctor.doctorID!, + obGyneProcedureListResponse: widget.obGyneProcedureListResponse!))); } Future navigateToDoctorProfile(context, docObject, docProfile, {isAppo, bool isContinueDentalPlan = false}) async { @@ -270,13 +301,17 @@ class DoctorView extends StatelessWidget { FadePage( page: DoctorProfile( doctor: docObject, - isLiveCareAppointment: isLiveCareAppointment!, + isLiveCareAppointment: widget.isLiveCareAppointment!, docProfileList: docProfile, isOpenAppt: isAppo, - isDoctorNameSearch: isDoctorNameSearch, + isDoctorNameSearch: widget.isDoctorNameSearch, isContinueDentalPlan: isContinueDentalPlan, ), ), ); } + + @override + // TODO: implement wantKeepAlive + bool get wantKeepAlive => true; } diff --git a/lib/pages/BookAppointment/widgets/reminder_dialog.dart b/lib/pages/BookAppointment/widgets/reminder_dialog.dart index a16876db..b3c39861 100644 --- a/lib/pages/BookAppointment/widgets/reminder_dialog.dart +++ b/lib/pages/BookAppointment/widgets/reminder_dialog.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; @@ -44,10 +45,10 @@ showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, S } } -Future _showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, +Future _showReminderDialog(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { return showDialog( - context: context, + context: providedContext, barrierDismissible: true, // user must tap button! builder: (BuildContext context) { return Dialog( @@ -81,7 +82,7 @@ Future _showReminderDialog(BuildContext context, DateTime dateTime, String if (onMultiDateSuccess == null) { CalendarUtils calendarUtils = await CalendarUtils.getInstance(); await calendarUtils.createOrUpdateEvent( - title: title ?? TranslationBase.of(context).reminderTitle + " " + doctorName, + title: title ?? TranslationBase.of(providedContext).reminderTitle + " " + doctorName, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, scheduleDateTime: dateTime, eventId: eventId); diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index a9a16ce7..88be72dd 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -260,7 +260,7 @@ class _CovidTimeSlotsState extends State with TickerProviderStat _events.forEach((key, value) { final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime endTime = startTime.add(const Duration(minutes: 20)); - meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); }); return meetings; } @@ -584,11 +584,12 @@ class MeetingDataSource extends CalendarDataSource { } class Meeting { - Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); String eventName; DateTime from; DateTime to; Color background; bool isAllDay; + String notes; } diff --git a/lib/pages/Covid-DriveThru/covid-payment-summary.dart b/lib/pages/Covid-DriveThru/covid-payment-summary.dart index a9a2af78..384b2422 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-summary.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-summary.dart @@ -420,7 +420,6 @@ class _CovidPaymentSummaryState extends State { addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID) { DoctorsListService service = new DoctorsListService(); service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { - print(res); getAppoQR(context); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart index 3b392501..946f6003 100644 --- a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart @@ -85,13 +85,13 @@ class _EROnlineCheckInBookAppointmentState extends State( value: item, - child: new Text(item.name!), + child: new Text(item.name! + " - " + item.distanceInKilometers.toString() + " " + TranslationBase.of(context).km), ); }).toList(), onChanged: (newValue) async { setState(() { - selectedHospital = newValue!; - projectDropdownValue = newValue.mainProjectID.toString(); + selectedHospital = newValue; + projectDropdownValue = newValue!.mainProjectID.toString(); }); }, ), @@ -145,9 +145,9 @@ class _EROnlineCheckInBookAppointmentState extends State with bool _supportsNFC = false; bool isPatientArrived = false; + late LocationUtils locationUtils; + @override void initState() { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); WidgetsBinding.instance.addPostFrameCallback((_) { // checkIfPatientHasArrived(); - checkPatientERClinicBalanceAmount(); + if (projectViewModel.isLogin) checkPatientERAdvanceBalance(); }); super.initState(); } @@ -48,9 +53,11 @@ class _EROnlineCheckInHomePageState extends State with return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}", - isShowDecPage: false, + isShowDecPage: true, showNewAppBar: true, showNewAppBarTitle: true, + description: TranslationBase.of(context).HHCNotAuthMsg, + imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/HHC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/HHC/en/0.png')], backgroundColor: Color(0xffF8F8F8), body: SingleChildScrollView( child: Padding( @@ -273,7 +280,7 @@ class _EROnlineCheckInHomePageState extends State with ), ), bottomSheet: Container( - height: 80, + height: projectViewModel.isLogin ? 80 : 1, color: CustomColors.white, padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), child: isPatientArrived @@ -321,7 +328,7 @@ class _EROnlineCheckInHomePageState extends State with }); } else { //NFCNotSupported - AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); + AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported, localContext: context); } }, color: CustomColors.green, @@ -352,10 +359,10 @@ class _EROnlineCheckInHomePageState extends State with print(response["GetProjectByNFC"]); int projectID = response['GetProjectByNFC'][0]["ProjectID"]; String projectName = response['GetProjectByNFC'][0]["ProjectName"]; + GifLoaderDialogUtils.hideDialog(context); if (isArrived) { autoGenerateInvoiceER(projectID); } else { - GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, FadePage( @@ -376,30 +383,12 @@ class _EROnlineCheckInHomePageState extends State with }); } - void checkIfPatientHasArrived() { - GifLoaderDialogUtils.showMyDialog(context); - ClinicListService ancillaryOrdersService = new ClinicListService(); - ancillaryOrdersService.checkIfPatientHasArrived(15, 10).then((response) { - print(response["IsPatientArrivedResponse"]); - isPatientArrived = response['IsPatientArrivedResponse']["IsPatientArrived"]; - GifLoaderDialogUtils.hideDialog(context); - // erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]); - setState(() {}); - }).catchError((err) { - AppToast.showErrorToast(message: err.toString()); - GifLoaderDialogUtils.hideDialog(context); - }); - } - autoGenerateInvoiceER(int projectID) { + GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.autoGenerateInvoiceERClinicWithNoPaymentDetails(projectID, true).then((res) { + service.autoGenerateInvoiceERClinic(projectID, 4, null, null, null, null, null, null, true).then((res) { GifLoaderDialogUtils.hideDialog(context); - if(res["MessageStatus"] == 1) { - _showMyDialog("Your online Check-In in the ER clinic has been done successfully.", context); - } else { - AppToast.showErrorToast(message: res["InvoiceResponse"]["Message"]); - } + _showMyDialog(TranslationBase.of(context).ERCheckInSuccess, context); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -435,15 +424,29 @@ class _EROnlineCheckInHomePageState extends State with ); } - void checkPatientERClinicBalanceAmount() { + void checkIfPatientHasArrived() { GifLoaderDialogUtils.showMyDialog(context); ClinicListService ancillaryOrdersService = new ClinicListService(); - ancillaryOrdersService.checkPatientERClinicBalanceAmount(10).then((response) { + ancillaryOrdersService.checkIfPatientHasArrived(15, 10).then((response) { + print(response["IsPatientArrivedResponse"]); + isPatientArrived = response['IsPatientArrivedResponse']["IsPatientArrived"]; + GifLoaderDialogUtils.hideDialog(context); + // erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]); + setState(() {}); + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + void checkPatientERAdvanceBalance() { + locationUtils.getCurrentLocation(); + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService ancillaryOrdersService = new ClinicListService(); + ancillaryOrdersService.checkPatientERAdvanceBalance(10).then((response) { print(response["BalanceAmount"]); isPatientArrived = response['BalanceAmount'] > 0; - // isPatientArrived = false; GifLoaderDialogUtils.hideDialog(context); - // erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]); setState(() {}); }).catchError((err) { AppToast.showErrorToast(message: err.toString()); diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart index 08cc78f4..13e5c733 100644 --- a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart @@ -46,7 +46,7 @@ class _EROnlineCheckInPaymentDetailsState extends State().getProjectDetailsForPayfort(projectId: widget.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { - payfortProjectDetailsRespModel = value; + payfortProjectDetailsRespModel = value!; }); applePayInsertRequest.clientRequestID = transID; @@ -403,12 +403,12 @@ class _EROnlineCheckInPaymentDetailsState extends State LandingPage()), (Route r) => false); + Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); } else { autoGenerateInvoiceER(paymentRes); } @@ -528,10 +535,11 @@ class _EROnlineCheckInPaymentDetailsState extends State createState() => _AdmissionNoticeState(); +} + +class _AdmissionNoticeState extends State { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + List inPatientServiceList = getAdmissionNoticeServicesList(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).admissionNoticeTitle, + body: Container( + margin: EdgeInsets.all(20.0), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 12, right: 12), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: inPatientServiceList.length, + itemBuilder: (BuildContext context, int index) { + return inPatientServiceList[index]; + }, + ), + ), + ], + ), + ), + ); + } + + List getAdmissionNoticeServicesList(BuildContext context) { + List serviceList = []; + + serviceList.add( + InkWell( + onTap: () { + // openBirthNotificationsPage(context); + viewModalBottomSheet(); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).admissionNoticeTitle, + imagePath: 'admission.svg', + subTitle: TranslationBase.of(context).insuranceSubtitle, + width: 50.0, + height: 40.0, + isInPatient: true, + ), + ), + ); + + return serviceList; + } + + void viewModalBottomSheet() { + showModalBottomSheet( + context: context, + builder: (context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 20), + child: Text( + "Admission Card", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 21, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Container( + padding: EdgeInsets.all(16.0), + height: 250, + child: Container( + decoration: cardRadius(20, color: Color(0xFFF2B353E)), + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + child: Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(MediaQuery.of(context).size.width / 4) + : containerBottomRightRadiusWithGradient(MediaQuery.of(context).size.width / 4), + child: Card( + color: Colors.transparent, + margin: EdgeInsets.zero, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + projectViewModel.authenticatedUserObject.user.firstName! + " " + projectViewModel.authenticatedUserObject.user.lastName!, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).roomNo + " " + (projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.roomID! : "Not assigned yet"), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.doctorName ?? "" + : projectViewModel.getAdmissionRequestInfoResponseModel.doctorName ?? "", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + // mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).clinic + + ": " + + (projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.clinicName!.toString() + : projectViewModel.getAdmissionRequestInfoResponseModel.clinicName!), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).hospital + + ": " + + (projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.projectName!.toString() + : projectViewModel.getAdmissionRequestInfoResponseModel.projectName!), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + mFlex(1), + ], + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 30), + child: DefaultButton( + TranslationBase.of(context).close.toUpperCase(), + () { + Navigator.pop(context); + }, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + ), + ], + ); + }); + } +} diff --git a/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart index 82e6ab96..690f1371 100644 --- a/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart +++ b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart @@ -13,6 +13,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:provider/provider.dart'; import 'package:share_plus/share_plus.dart'; +import 'package:url_launcher/url_launcher.dart'; class InPatientPendingAdvancePayment extends StatefulWidget { InPatientAdvanceResponseModel inPatientAdvanceResponseModel; @@ -32,7 +33,7 @@ class _InPatientPendingAdvancePaymentState extends State { (projectViewModel.user.firstNameN! + " " + projectViewModel.user.lastNameN!), projectViewModel.user.mobileNumber!, assistText.text, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showSuccessToast(message: TranslationBase.of(context).successSendReport); - Navigator.of(context).pop(); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(context).successSendReport); + Navigator.of(context).pop(); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage'], localContext: context); + Navigator.of(context).pop(); + } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); diff --git a/lib/pages/InPatientServices/inpatient_general_consent.dart b/lib/pages/InPatientServices/inpatient_general_consent.dart new file mode 100644 index 00000000..f0164cda --- /dev/null +++ b/lib/pages/InPatientServices/inpatient_general_consent.dart @@ -0,0 +1,527 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InPatientGeneralConsent extends StatelessWidget { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).InPatientServicesHeader, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(21.0), + child: Text( + TranslationBase.of(context).generalConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + Expanded( + child: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + child: Card( + elevation: 0.0, + margin: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent1, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).hospitalRules, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).communicationConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent3, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).releaseConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent4, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent5, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).valuables, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent6, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).financialConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent7, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).dataSharingConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent8, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).permissionLeaveConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent9, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).observeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent10, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).noGuaranteeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent11, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).disputeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent12, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).patientsRightsConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent13, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).acknowledgementConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent14, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 21.0, right: 21.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + acceptRejectConsent(context, 0); + }, + child: Text(TranslationBase.of(context).reject, style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + acceptRejectConsent(context, 1); + }, + child: Text(TranslationBase.of(context).acceptLbl, style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + void acceptRejectConsent(BuildContext context, int status) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .insertForGeneralAdmissionConsent( + projectViewModel.user.patientID!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.clinicID! : projectViewModel.getAdmissionRequestInfoResponseModel.clinicId!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, + status, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + AppToast.showErrorToast(message: res["SuccessMsg"]); + } else { + AppToast.showErrorToast(message: res["endUserMessage"]); + } + Navigator.pop(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/InPatientServices/inpatient_home.dart b/lib/pages/InPatientServices/inpatient_home.dart index 4aba8274..9987d501 100644 --- a/lib/pages/InPatientServices/inpatient_home.dart +++ b/lib/pages/InPatientServices/inpatient_home.dart @@ -1,9 +1,11 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/InPatientServices/get_general_instructions_response_model.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/admission_notice.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/birth_notification.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/general_instructions.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/help_PRO.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_advance_payment.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_general_consent.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/meal_plan.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/medical_instructions.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; @@ -78,6 +80,23 @@ class _InPatientServicesHomeState extends State { List getInPatientServicesList(BuildContext context) { List serviceList = []; + serviceList.add( + InkWell( + onTap: () { + openPatientGeneralConsent(); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).generalConsentTitle, + imagePath: 'general_instructions.svg', + subTitle: TranslationBase.of(context).generalConsentSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: true, + ), + ), + ); + serviceList.add( InkWell( onTap: () { @@ -180,6 +199,23 @@ class _InPatientServicesHomeState extends State { ), ); + serviceList.add( + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: AdmissionNotice())); + // if (isReceivePrescriptionEnabled) receivePrescriptionAPI(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).admissionNoticeTitle, + imagePath: 'admission_notice.svg', + subTitle: TranslationBase.of(context).admissionNoticeSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: true), + ), + ); + serviceList.add( InkWell( onTap: () { @@ -241,18 +277,17 @@ class _InPatientServicesHomeState extends State { void checkDischargeMedications(BuildContext context) { ClinicListService service = new ClinicListService(); GifLoaderDialogUtils.showMyDialog(context); - // service.getDischargeMedicationOrder(projectViewModel.getAdmissionInfoResponseModel).then((res) { - // print(res["PatientHasDischargeMedicineList"].length); - // setState(() { - // if (res["PatientHasDischargeMedicineList"].length != 0) { - // isReceivePrescriptionEnabled = true; - // } - // }); - // GifLoaderDialogUtils.hideDialog(context); - // }).catchError((err) { - // GifLoaderDialogUtils.hideDialog(context); - // print(err); - // }); + service.getDischargeMedicationOrder(projectViewModel.getAdmissionInfoResponseModel).then((res) { + setState(() { + if (res["PatientHasDischargeMedicineList"].length != 0) { + isReceivePrescriptionEnabled = true; + } + }); + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } void callReceivePrescriptionAPI(BuildContext context) { @@ -272,32 +307,41 @@ class _InPatientServicesHomeState extends State { void openBirthNotificationsPage(BuildContext context) { ClinicListService service = new ClinicListService(); GifLoaderDialogUtils.showMyDialog(context); - service.getBirthNotification(projectViewModel.user.patientID!, context).then((res) { + service + .getBirthNotification( + projectViewModel.user.patientID!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, + projectViewModel.isArabic ? 1 : 2, + context) + .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["MessageStatus"] == 1) { - print(res['birthNotification']); Navigator.push(context, FadePage(page: BirthNotification())); } else { - AppToast.showErrorToast(message: res["endUserMessage"]); + AppToast.showErrorToast(message: res["endUserMessage"], localContext: context); } }).catchError((err) { print(err); }); } + void openPatientGeneralConsent() { + Navigator.push(context, FadePage(page: InPatientGeneralConsent())); + } + void openGeneralInstructions(BuildContext context) { ClinicListService service = new ClinicListService(); GifLoaderDialogUtils.showMyDialog(context); - service.getGeneralInstructions(projectViewModel.inPatientProjectID, context).then((res) { + service.getGeneralInstructions(projectViewModel.inPatientProjectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { if (res['generalInstructions'].length != 0) { List getGeneralInstructionsList = []; res['generalInstructions'].forEach((v) { getGeneralInstructionsList.add(new GetGeneralInstructions.fromJson(v)); }); GifLoaderDialogUtils.hideDialog(context); - print(res['generalInstructions']); Navigator.push(context, FadePage(page: GeneralInstructions(getGeneralInstructionsList: getGeneralInstructionsList))); } else { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: TranslationBase.of(context).noGeneralInstructions); } }).catchError((err) { @@ -308,14 +352,13 @@ class _InPatientServicesHomeState extends State { void openMedicalInstructions(BuildContext context) { ClinicListService service = new ClinicListService(); GifLoaderDialogUtils.showMyDialog(context); - service.getMedicalInstructions(projectViewModel.inPatientProjectID, context).then((res) { + service.getMedicalInstructions(projectViewModel.inPatientProjectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { if (res['MedicalInstruction'] != null && res['MedicalInstruction'].length != 0) { List getMedicalInstructionsList = []; res['MedicalInstruction'].forEach((v) { getMedicalInstructionsList.add(new GetMedicalInstructions.fromJson(v)); }); GifLoaderDialogUtils.hideDialog(context); - print(res['MedicalInstruction']); Navigator.push(context, FadePage(page: MedicalInstructionsPage(getMedicalInstructionsList: getMedicalInstructionsList))); } else { GifLoaderDialogUtils.hideDialog(context); @@ -334,11 +377,12 @@ class _InPatientServicesHomeState extends State { projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isArabic ? 1 : 2, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["MessageStatus"] == 1) { - if (res['responseInpatient'] != null) { + if (res['responseInpatient'] != null && res['responseInpatient']['responseInpatientAdvanceInfo'] != null && res['responseInpatient']['responseInpatientAdvanceInfo'].length != 0) { inPatientAdvanceResponseModel = InPatientAdvanceResponseModel.fromJson(res["responseInpatient"]); Navigator.push(context, FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); @@ -356,8 +400,6 @@ class _InPatientServicesHomeState extends State { } void checkCurrentTime(BuildContext context) { - print(DateTime.now().hour); - print(DateTime.now().minute); if (DateTime.now().hour >= 7 && DateTime.now().hour <= 22) { Navigator.push(context, FadePage(page: HelpPRO())); } else { @@ -373,8 +415,6 @@ class _InPatientServicesHomeState extends State { } bool checkAdmissionRequestDate() { - print(DateUtil.convertStringToDate(projectViewModel.getAdmissionRequestInfoResponseModel.expectedAdmissionDate)); - print(DateUtil.convertStringToDate(projectViewModel.getAdmissionRequestInfoResponseModel.expectedAdmissionDate).difference(DateTime.now()).inHours); if (DateUtil.convertStringToDate(projectViewModel.getAdmissionRequestInfoResponseModel.expectedAdmissionDate).difference(DateTime.now()).inHours > 24) { return false; } diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 7d552c4f..db6eb173 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel. import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; @@ -299,23 +300,68 @@ class _AppointmentDetailsState extends State with SingleTick } void goToBookConfirm() { - if (DocAvailableAppointments.areSlotsAvailable) - navigateToBookConfirm(context); - else - AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) { + canPayForWalkInAppointment(); + } else { + if (DocAvailableAppointments.areSlotsAvailable) + navigateToBookConfirm(context); + else + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + + canPayForWalkInAppointment() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.canPayForWalkInAppointment(widget.appo.clinicID!, widget.appo.projectID!, widget.appo.doctorID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + navigateToWaitingAppointment(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); + print(err); + }); + } + + Future navigateToWaitingAppointment(context) async { + DoctorList doctor = new DoctorList(); + doctor.name = widget.appo.doctorNameObj; + doctor.clinicID = widget.appo.clinicID; + doctor.projectID = widget.appo.projectID; + doctor.doctorID = widget.appo.doctorID; + doctor.clinicName = widget.appo.clinicName; + doctor.projectName = widget.appo.projectName; + doctor.doctorTitle = widget.appo.doctorTitle; + doctor.doctorImageURL = widget.appo.doctorImageURL; + doctor.speciality = widget.appo.doctorSpeciality; + doctor.nationalityFlagURL = ""; + doctor.doctorRate = widget.appo.doctorRate; + doctor.noOfPatientsRate = widget.appo.noOfPatientsRate; + + projectViewModel?.setWaitingAppointmentProjectID(widget.appo.projectID!); + projectViewModel?.setWaitingAppointmentDoctor(doctor); + Navigator.push( + context, + FadePage( + page: WaitingAppointmentInfo(), + ), + ); } Future navigateToBookConfirm(context) async { Navigator.push( - context, - FadePage( - page: BookConfirm( + context, + FadePage( + page: BookConfirm( doctor: getDoctorObject(), isLiveCareAppointment: widget.appo.isLiveCareAppointment!, selectedDate: DocAvailableAppointments.selectedDate!, selectedTime: DocAvailableAppointments.selectedTime!, initialSlotDuration: 0, - ))); + isWalkinAppointment: false, + ), + ), + ); } void getDoctorRatingsDetails() { diff --git a/lib/pages/MyAppointments/MyAppointments.dart b/lib/pages/MyAppointments/MyAppointments.dart index c279a9ab..44d06899 100644 --- a/lib/pages/MyAppointments/MyAppointments.dart +++ b/lib/pages/MyAppointments/MyAppointments.dart @@ -405,6 +405,7 @@ class _MyAppointmentsState extends State with SingleTickerProvid Widget _appointmentExpandableList(List _patientAppointmentList) { return ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), padding: EdgeInsets.only(top: 12), separatorBuilder: (context, index) { @@ -432,7 +433,8 @@ class _MyAppointmentsState extends State with SingleTickerProvid FadePage( page: AppointmentDetails( appo: _appointmentResult, - parentIndex: _currentPage, + // parentIndex: _currentPage, + parentIndex: _appointmentResult.patientStatusType == 42 ? 1 : 0, ), ), ).then((value) { diff --git a/lib/pages/MyAppointments/models/BookedButtons.dart b/lib/pages/MyAppointments/models/BookedButtons.dart index 66e4366f..39aed7cc 100644 --- a/lib/pages/MyAppointments/models/BookedButtons.dart +++ b/lib/pages/MyAppointments/models/BookedButtons.dart @@ -39,6 +39,7 @@ class BookedButtons { "icon": "hosp_location.svg", "caller": "navigateToProject", }, - {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"} + {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}, + // {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"} ]; } diff --git a/lib/pages/MyAppointments/models/ConfirmedButtons.dart b/lib/pages/MyAppointments/models/ConfirmedButtons.dart index 7ba3ce1c..d49723e9 100644 --- a/lib/pages/MyAppointments/models/ConfirmedButtons.dart +++ b/lib/pages/MyAppointments/models/ConfirmedButtons.dart @@ -19,6 +19,7 @@ class ConfirmedButtons { // "icon": "assets/images/new-design/generate_visit_ticket.png", // "caller": "visitTicket" // }, - {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"} + {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}, + // {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"} ]; } diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 6347d3f4..61fddab8 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -27,9 +27,11 @@ import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_it import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; @@ -40,6 +42,7 @@ import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:huawei_map/huawei_map.dart' as hmsMap; import 'package:intl/intl.dart'; import 'package:map_launcher/map_launcher.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -128,8 +131,7 @@ class _AppointmentActionsState extends State { .parse(DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.appo.appointmentDate!), widget.projectViewModel!.isArabic) + " " + widget.appo.startTime!), //DateUtil.convertStringToDate(widget.appo.appointmentDate), widget.appo.doctorNameObj!, - "", - + widget.appo.appointmentNo.toString(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.appo.appointmentDate!), widget.projectViewModel!.isArabic), // DateUtil.formatDateToTime(DateUtil.convertStringToDate(widget.appo.appointmentDate)), widget.appo.startTime!, @@ -178,6 +180,31 @@ class _AppointmentActionsState extends State { navigateToInsertComplaint(); locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint'); break; + + case "goToNavigation": + initPenguinSDK(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'navigate to clinic'); + break; + } + } + + initPenguinSDK() async { + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = widget.appo.clinicID.toString(); + // data.clinicId = "49"; + data.patientId = widget.appo.patientID.toString(); + data.projectId = widget.appo.projectID.toString(); + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", widget.projectViewModel!.isArabic ? "ar" : "en", widget.projectViewModel!.authenticatedUserObject.user.patientID.toString(), details: data); + }); } } diff --git a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart index 38c09047..9660a616 100644 --- a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart +++ b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart @@ -253,7 +253,7 @@ class _CovidTimeSlotsState extends State with TickerProviderSta _events!.forEach((key, value) { final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime endTime = startTime.add(const Duration(minutes: 20)); - meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); }); return meetings; } @@ -534,11 +534,12 @@ class MeetingDataSource extends CalendarDataSource { } class Meeting { - Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); String eventName; DateTime from; DateTime to; Color background; bool isAllDay; + String notes; } diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 91092bb3..bd860008 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -29,10 +29,12 @@ import 'package:diplomaticquarterapp/services/livecare_services/livecare_provide import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -50,6 +52,7 @@ import 'package:flutter_countdown_timer/current_remaining_time.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; class ToDo extends StatefulWidget { @@ -354,23 +357,56 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16), ), ), - InkWell( - onTap: () { - navigateToAppointmentDetails(context, appoList[index]); - }, - child: Padding( - padding: const EdgeInsets.only(top: 0.0), - child: Text( - TranslationBase.of(context).moreDetails, - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w600, - color: CustomColors.accentColor, - letterSpacing: -0.48, - height: 25 / 16, - decoration: TextDecoration.underline), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + navigateToAppointmentDetails(context, appoList[index]); + }, + child: Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + TranslationBase.of(context).moreDetails, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 25 / 16, + decoration: TextDecoration.underline), + ), + ), ), - ), + if (projectViewModel.isIndoorNavigationEnabled && projectViewModel.havePrivilege(107) && appoList[index].projectID == 130) + InkWell( + onTap: () { + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = appoList[index].clinicID.toString(); + // data.clinicId = "46"; + data.patientId = appoList[index].patientID.toString(); + data.projectId = appoList[index].projectID.toString(); + initPenguinSDK(data); + }, + child: Column( + children: [ + SvgPicture.asset( + "assets/images/new/Indoor_nav_appo.svg", + ), + Text( + TranslationBase.of(context).clinicLocation, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 25 / 16, + decoration: TextDecoration.underline), + ), + ], + ), + ), + ], ), ], ), @@ -530,6 +566,21 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { ); } + initPenguinSDK(NavigationClinicDetails data) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString(), details: data); + }); + } + } + String getNextActionImage(nextAction) { switch (nextAction) { case 0: @@ -851,6 +902,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { isLiveCareAppointment: false, isObGyneAppointment: true, doctorsList: docList, + isDoctorSearchResult: false, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, obGyneProcedureListResponse: obGyneProcedureListResponse))); } @@ -949,7 +1001,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { okText: "Update insurance", cancelText: "Continue as cash", okFunction: () => {openUpdateInsurance()}, - cancelFunction: () => {continueAsCash(appo)}); + cancelFunction: () => {continueAsCash(appo, false)}); dialog.showAlertDialog(context); } }).catchError((err) { @@ -963,19 +1015,24 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { Navigator.push(context, FadePage(page: InsuranceUpdate())); } - void continueAsCash(AppoitmentAllHistoryResultList appo) { + void continueAsCash(AppoitmentAllHistoryResultList appo, bool isLiveCareAppointment) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service.convertPatientToCash(appo.projectID!).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["MessageStatus"] == 1) { - getPatientShare(context, appo); + if (isLiveCareAppointment) { + getLiveCareAppointmentPatientShare(context, service, appo); + } else { + getPatientShare(context, appo); + } // getToDoCount(); } else { AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); print(err); }); } @@ -1015,7 +1072,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { okText: TranslationBase.of(context).updateInsuranceText, cancelText: TranslationBase.of(context).continueCash, okFunction: () => {openUpdateInsurance()}, - cancelFunction: () => {continueAsCash(appo)}); + cancelFunction: () => {continueAsCash(appo, false)}); dialog.showAlertDialog(context); } } @@ -1028,11 +1085,40 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { } getLiveCareAppointmentPatientShare(context, DoctorsListService service, AppoitmentAllHistoryResultList appo) { + String errorMsg = ""; GifLoaderDialogUtils.showMyDialog(context); service.getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), appo.clinicID, appo.projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); widget.patientShareResponse = new PatientShareResponse.fromJson(res); - openPaymentDialog(appo, widget.patientShareResponse!); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && isEligible) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(appo, true)}); + dialog.showAlertDialog(context); + } + } + + // openPaymentDialog(appo, widget.patientShareResponse!); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -1114,7 +1200,6 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); } }); - projectViewModel.analytics.todoList.to_do_list_pay_now(appo); } @@ -1445,6 +1530,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); log("failureResult: ${failureResult.toString()}"); AppToast.showErrorToast(message: failureResult.toString()); }, @@ -1463,7 +1549,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { }).catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err.toString()); }); } diff --git a/lib/pages/conference/zoom/call_screen.dart b/lib/pages/conference/zoom/call_screen.dart index 2ba0e49e..74a87ad2 100644 --- a/lib/pages/conference/zoom/call_screen.dart +++ b/lib/pages/conference/zoom/call_screen.dart @@ -472,7 +472,7 @@ class _CallScreenState extends State { ], ), ); - if (errorType == Errors.SessionJoinFailed || errorType == Errors.SessionDisconncting) { + if (errorType == Errors.SessionJoinFailed || errorType == Errors.SessionDisconnecting) { Timer( const Duration(milliseconds: 1000), () => Navigator.pop(context), diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 7441f591..d01554ea 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -45,6 +45,9 @@ class _HomePageFragment2State extends State { void initState() { // TODO: implement initState super.initState(); + + // getPatientAppointmentHistory1(); + // getFamilyFiles(); } initialiseHmgServices(bool isLogin) { @@ -52,7 +55,14 @@ class _HomePageFragment2State extends State { hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); hmgServices.add(HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); - hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).onlineCheckIn, "assets/images/new/emergency.svg", isLogin)); + + projectViewModel.isIndoorNavigationEnabled + ? hmgServices.add(HmgServices(2, TranslationBase.of(context).hospitalNavigationTitle, TranslationBase.of(context).hospitalNavigationSubtitle, "assets/images/new/indoor_nav_home.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(107))) + : hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + hmgServices.add( + HmgServices(9, TranslationBase.of(context).emergency, TranslationBase.of(context).checkinOptions, "assets/images/new/emergency.svg", isLogin, isLocked: !projectViewModel.havePrivilege(108))); hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); hmgServices.add(HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); @@ -66,9 +76,19 @@ class _HomePageFragment2State extends State { // hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); // hmgServices.add(new HmgServices(1, TranslationBase.of(context).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/CoronaIcon.svg", isLogin)); // hmgServices.add(new HmgServices(2, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); + + projectViewModel.isIndoorNavigationEnabled + ? hmgServices.add(HmgServices(2, TranslationBase.of(context).hospitalNavigationTitle, TranslationBase.of(context).hospitalNavigationSubtitle, "assets/images/new/indoor_nav_home.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(107))) + : hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + hmgServices.add(new HmgServices(9, TranslationBase.of(context).emergency, TranslationBase.of(context).checkinOptions, "assets/images/new/emergency.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(108))); hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); hmgServices.add(new HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); - hmgServices.add(new HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + // hmgServices.add(new HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + hmgServices.add(new HmgServices(6, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); hmgServices.add(new HmgServices(7, "H\u2082O", TranslationBase.of(context).dailyWater, "assets/images/new/h2o.svg", isLogin)); hmgServices.add(new HmgServices(8, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.svg", isLogin)); @@ -296,15 +316,16 @@ class _HomePageFragment2State extends State { child: ServicesView( new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false), 23, - true)), + true, + projectViewModel)), ), ), Expanded( flex: 4, child: AspectRatio( aspectRatio: 1.0, - child: ServicesView( - new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, true)), + child: ServicesView(new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, + true, projectViewModel)), ), ], ), @@ -322,7 +343,7 @@ class _HomePageFragment2State extends State { itemCount: hmgServices.length, padding: EdgeInsets.zero, itemBuilder: (BuildContext context, int index) { - return ServicesView(hmgServices[index], index, true); + return ServicesView(hmgServices[index], index, true, projectViewModel); }, ), ), @@ -341,7 +362,9 @@ class _HomePageFragment2State extends State { itemCount: hmgServices.length, padding: EdgeInsets.zero, itemBuilder: (BuildContext context, int index) { - return ServicesView(hmgServices[index], index, true); + // return ServicesView(hmgServices[index], index, true, projectViewModel, + // isLocked: (hmgServices[index].action == 2 && projectViewModel.isIndoorNavigationEnabled) ? !projectViewModel.havePrivilege(107) : false); + return ServicesView(hmgServices[index], index, true, projectViewModel, isLocked: hmgServices[index].isLocked); }, ), ), @@ -489,8 +512,7 @@ class _HomePageFragment2State extends State { flex: 1, child: InkWell( onTap: () { - if (projectViewModel.havePrivilege(100)) - widget.onPharmacyClick!(); + if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!(); }, child: Stack(children: [ Container( diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart index 9b52958b..af02e200 100644 --- a/lib/pages/landing/home_page_2.dart +++ b/lib/pages/landing/home_page_2.dart @@ -33,6 +33,11 @@ class _HomePageState2 extends State { PharmacyModuleViewModel pharmacyModuleViewModel = locator(); late ProjectViewModel projectViewModel; + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index ebe6e67b..05d90571 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -44,7 +44,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; +// import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; @@ -76,8 +76,7 @@ class LandingPage extends StatefulWidget { class _LandingPageState extends State with WidgetsBindingObserver { var authProvider = new AuthProvider(); - AppointmentRateViewModel appointmentRateViewModel = - locator(); + AppointmentRateViewModel appointmentRateViewModel = locator(); int currentTab = 0; late PageController pageController; @@ -94,8 +93,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { bool _showBottomNavigationBar = true; ///inject the user data - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; final authService = new AuthProvider(); @@ -122,22 +120,17 @@ class _LandingPageState extends State with WidgetsBindingObserver { "appointmentdate": "2022-01-19", "appointmenttime": "12:10", "PatientName": "Testing", - "session_id": - "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", + "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", "token": "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", - "DoctorImageURL": - "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", "callerID": "9920", "PatientID": "1231755", "is_call": "true" }; void _requestIOSPermissions() { - flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - IOSFlutterLocalNotificationsPlugin>() - ?.requestPermissions( + flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions( alert: true, badge: true, sound: true, @@ -153,8 +146,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { return Future.value(false); } else { DateTime now = DateTime.now(); - if (currentBackPressTime == null || - now.difference(currentBackPressTime!) > Duration(seconds: 2)) { + if (currentBackPressTime == null || now.difference(currentBackPressTime!) > Duration(seconds: 2)) { currentBackPressTime = now; AppToast.showToast(message: TranslationBase.of(context).pressAgain); return Future.value(false); @@ -169,18 +161,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { List imagesInfo = []; imagesInfo.add( ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), ); imagesInfo.add( ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), ); Navigator.push( @@ -199,11 +187,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { } if (tab == 4) { List imagesInfo = []; - imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); Navigator.push( context, @@ -248,8 +233,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { }); }); - projectViewModel.analytics.bottomTabNavigation - .log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin); + projectViewModel.analytics.bottomTabNavigation.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin); } getToDoCount() { @@ -260,11 +244,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); - toDoProvider.setState( - res['AppointmentActiveNumber'], - res['AncillaryOrderListCount'], - true, - toDoProvider.notificationsCount); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); } else {} }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -303,10 +283,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { WidgetsBinding.instance.addPostFrameCallback((_) { if (projectViewModel.isLogin && !projectViewModel.isLoginChild) { - int languageID = - Provider.of(context, listen: false).isArabic - ? 1 - : 2; + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; familyFileProvider.getSharedRecordByStatus(languageID); } // Future.delayed(Duration(seconds: 3)).then((result) async { @@ -322,31 +299,34 @@ class _LandingPageState extends State with WidgetsBindingObserver { // HMGNetworkConnectivity(context).start(); _firebaseMessaging.getToken().then((String? token) { - print("Firebase Token: " + token!); - sharedPref.setString(PUSH_TOKEN, token!); - if (Platform.isIOS) { - FirebaseMessaging.instance.getAPNSToken().then((value) { - print("Push APNS getToken: " + value!); - AppSharedPreferences().setString(APNS_TOKEN, value); - AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, value); - }); - // voIPKit.getVoIPToken().then((value) { - // print('🎈 example: getVoIPToken: $value'); - // AppSharedPreferences().setString(APNS_TOKEN, value!); - // // getOneSignalVOIPToken(value); - // }); - } + // print("Firebase Token: " + token!); + sharedPref.setString(PUSH_TOKEN, token!); + if (Platform.isIOS) { + FirebaseMessaging.instance.getAPNSToken().then((value) { + print("Push APNS getToken: " + value!); + AppSharedPreferences().setString(APNS_TOKEN, value); + AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, value); + }); + // voIPKit.getVoIPToken().then((value) { + // print('🎈 example: getVoIPToken: $value'); + // AppSharedPreferences().setString(APNS_TOKEN, value!); + // // getOneSignalVOIPToken(value); + // }); + } if (token != null) { DEVICE_TOKEN = token; if (!projectViewModel.isLoginChild) { checkUserStatus(token); } } + }).catchError((err) { + print(err); }); startZoom(); // HMG_Geofencing(context).loadZones().then((instance) => instance.init()); } - void startZoom(){ + + void startZoom() { var zoom = ZoomVideoSdk(); InitConfig initConfig = InitConfig( domain: "zoom.us", @@ -476,20 +456,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { getNotificationCount(token) async { if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { authService.getDashboard().then((value) => { if (value != null) { setState(() { - notificationCount = value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] > - 99 - ? '99+' - : value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] - .toString(); + notificationCount = + value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); model.setState(model.count, 0, true, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount); }) @@ -519,11 +493,9 @@ class _LandingPageState extends State with WidgetsBindingObserver { getText(currentTab).toUpperCase(), style: TextStyle( fontWeight: FontWeight.bold, - color: currentTab == 0 - ? CustomColors.backgroudGreyColor - : Theme.of(context).textTheme.headline1!.color, - fontFamily: - projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + color: currentTab == 0 ? CustomColors.backgroudGreyColor : CustomColors.accentColor, + // : Theme.of(context).textTheme.headline1!.color, + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), // bold: true, ), leading: Builder( @@ -532,14 +504,10 @@ class _LandingPageState extends State with WidgetsBindingObserver { children: [ currentTab == 0 ? IconButton( - icon: SvgPicture.asset( - "assets/images/new/menu.svg"), - color: Theme.of(context) - .textTheme - .headline1! - .color, - onPressed: () => - Scaffold.of(context).openDrawer(), + icon: SvgPicture.asset("assets/images/new/menu.svg"), + // color: Theme.of(context).textTheme.headline1!.color, + color: CustomColors.white, + onPressed: () => Scaffold.of(context).openDrawer(), ) : IconButton( icon: Icon(Icons.arrow_back), @@ -550,9 +518,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { pageController.jumpToPage(0); }, ), - projectViewModel.isLogin && - model.notificationsCount != null && - !projectViewModel.isLoginChild + projectViewModel.isLogin && model.notificationsCount != null && !projectViewModel.isLoginChild ? Positioned( right: projectViewModel.isArabic ? 35 : 0, top: 5, @@ -570,8 +536,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { model.notificationsCount.toString(), style: TextStyle( color: Colors.white, - fontSize: - projectViewModel.isArabic ? 8 : 9, + fontSize: projectViewModel.isArabic ? 8 : 9, ), textAlign: TextAlign.center, ), @@ -655,16 +620,15 @@ class _LandingPageState extends State with WidgetsBindingObserver { index: currentTab, ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, - floatingActionButton: - (projectViewModel.havePrivilege(34) && currentTab == 0) - ? FloatingButton( - elevation: true, - onTap: () { - changeCurrentTab(2); - projectViewModel.analytics.appointment.book_appointment(); - }, - ) - : null); + floatingActionButton: (projectViewModel.havePrivilege(34) && currentTab == 0) + ? FloatingButton( + elevation: true, + onTap: () { + changeCurrentTab(2); + projectViewModel.analytics.appointment.book_appointment(); + }, + ) + : null); } triggerRobot() { @@ -692,25 +656,16 @@ class _LandingPageState extends State with WidgetsBindingObserver { await PushNotificationHandler.getInstance().requestPermissions(); // authService.selectDeviceImei(token).then((SelectDeviceIMEIRES? value) => setUserValues(value)); if (authenticatedUserObject.isLogin) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { - authService - .registeredAuthenticatedUser(data, token, 0, 0) - .then((res) => {}); + authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {}); authService.getDashboard().then((value) async { setState(() { if (value != null) { - notificationCount = value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] > - 99 - ? '99+' - : value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] - .toString(); + notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); model.setState(model.count, 0, true, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount); - FlutterAppIconBadge.updateBadge(int.parse(notificationCount)); + // FlutterAppIconBadge.updateBadge(int.parse(notificationCount)); } }); // if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) { diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index 241b1b19..b336887e 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -4,7 +4,9 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; @@ -32,14 +34,20 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/location_selection_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../../locator.dart'; @@ -53,8 +61,10 @@ class ServicesView extends StatelessWidget { PharmacyModuleViewModel pharmacyModuleViewModel = locator(); late LocationUtils locationUtils; bool isHomePage; + late ProjectViewModel projectViewModel; + bool isLocked; - ServicesView(this.hmgServices, this.index, this.isHomePage); + ServicesView(this.hmgServices, this.index, this.isHomePage, this.projectViewModel, {this.isLocked = false}); @override Widget build(BuildContext context) { @@ -160,12 +170,58 @@ class ServicesView extends StatelessWidget { ], ), ), + isLocked + ? Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadiusWithGradientServices(20, lightColor: Colors.grey.withOpacity(0.6), darkColor: Colors.grey.withOpacity(0.6)), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + : Container() ], ), ), ); } + openNavigationProjectSelection(BuildContext context) { + int _selectedHospitalIndex = 0; + List projectsListLocal = []; + Utils.navigationProjectsList.forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + showDialog( + context: context, + builder: (cxt) => LocationSelectionDialog( + isArabic: projectViewModel.isArabic, + data: projectsListLocal, + selectedIndex: _selectedHospitalIndex, + onValueSelected: (index) { + _selectedHospitalIndex = index; + initPenguinSDK(projectsListLocal[index].iD); + }, + ), + ); + } + + initPenguinSDK(int projectID) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString()); + }); + } // + } + handleHomePageServices(HmgServices hmgServices, BuildContext context) { if (hmgServices.action == 0) { Navigator.push(context, FadePage(page: Search())); @@ -173,8 +229,13 @@ class ServicesView extends StatelessWidget { } else if (hmgServices.action == 1) { openLiveCare(context); } else if (hmgServices.action == 2) { - Navigator.push(context, FadePage(page: EROnlineCheckInHomePage())); - locator().hmgServices.logServiceName('ER Online CheckIn'); + // initPenguinSDK(); + if (projectViewModel.isIndoorNavigationEnabled) { + if (!isLocked) openNavigationProjectSelection(context); + } else { + Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); + locator().hmgServices.logServiceName('emergency service'); + } } else if (hmgServices.action == 3) { Navigator.push(context, FadePage(page: HomeHealthCarePage())); locator().hmgServices.logServiceName('home health care'); @@ -196,6 +257,9 @@ class ServicesView extends StatelessWidget { } else if (hmgServices.action == 23) { Navigator.push(context, FadePage(page: InPatientServicesHome())); locator().hmgServices.logServiceName('find us reach us'); + } else if (hmgServices.action == 9) { + if (!isLocked) Navigator.push(context, FadePage(page: EROnlineCheckInHomePage())); + locator().hmgServices.logServiceName('ER Online CheckIn'); } } @@ -267,10 +331,8 @@ class ServicesView extends StatelessWidget { } else if (hmgServices.action == 21) { Navigator.of(context).push( MaterialPageRoute( - builder: (BuildContext context) => MyWebView( - title: "HMG News", - selectedUrl:"https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", - ), + builder: (BuildContext context) => MyWebView(title: "HMG News", selectedUrl: "https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", + ), ), ); locator().hmgServices.logServiceName('latest news'); diff --git a/lib/pages/livecare/live_care_payment_page.dart b/lib/pages/livecare/live_care_payment_page.dart index b6c0561d..a1bb6cb1 100644 --- a/lib/pages/livecare/live_care_payment_page.dart +++ b/lib/pages/livecare/live_care_payment_page.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; @@ -13,6 +15,7 @@ import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -282,53 +285,87 @@ class _LiveCarePatmentPageState extends State { Container( padding: EdgeInsets.all(12), color: Colors.white, - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).cancel, - () { - if (widget.isPharmaLiveCare) cancelAPI(); - Navigator.pop(context, false); - }, - ), - ), - mWidth(12), - Expanded( - child: DefaultButton( - TranslationBase.of(context).next, - () { - if (_selected == 0) { - AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); - } else { - if (widget.isPharmaLiveCare) { - Navigator.pop(context, true); - } else { - askVideoCallPermission().then((value) async { - if (value == true) { - locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context); - locationUtils.getCurrentLocation(callBack: (value) { - print(value); - }); - if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { - await drawOverAppsMessageDialog(context).then((value) { - return false; - }); - } else { - Navigator.pop(context, true); - projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); - } + child: Column( + children: [ + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancel, + () { + if (widget.isPharmaLiveCare) cancelAPI(); + Navigator.pop(context, false); + }, + ), + ), + mWidth(12), + Expanded( + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (_selected == 0) { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + } else { + if (widget.isPharmaLiveCare) { + Navigator.pop(context, true); } else { - openPermissionsDialog(); + askVideoCallPermission().then((value) async { + if (value == true) { + locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + print(value); + }); + if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { + await drawOverAppsMessageDialog(context).then((value) { + return false; + }); + } else { + Navigator.pop(context, true); + projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); + } + } else { + openPermissionsDialog(); + } + }); } - }); - } - } - }, - color: CustomColors.green, - ), + } + }, + color: CustomColors.green, + ), + ), + ], ), + widget.getERAppointmentFeesList.isCash! + ? Column( + children: [ + mHeight(10.0), + Text( + TranslationBase.of(context).cashAmountUpdateInsurance, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + ), + ), + mHeight(5.0), + DefaultButton( + TranslationBase.of(context).updateInsuranceText, + () { + Navigator.pop(context, null); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + color: Color(0xffEAA118), + textColor: Colors.white, + ), + ], + ) + : Container(), ], ), ), diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index 4c14eeb2..6381ce8a 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -171,7 +171,7 @@ class _LiveCareHomeState extends State with SingleTickerProviderSt }); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err, localContext: context); print(err); }); } diff --git a/lib/pages/livecare/video-call-web-page.dart b/lib/pages/livecare/video-call-web-page.dart index 46a29924..f755d1b0 100644 --- a/lib/pages/livecare/video-call-web-page.dart +++ b/lib/pages/livecare/video-call-web-page.dart @@ -14,7 +14,7 @@ class VideoCallWebPage extends StatelessWidget{ final String receiverId; final String callerId; VideoCallWebPage({required this.receiverId, required this.callerId}){ - request = URLRequest(url: Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId")); + request = URLRequest(url: WebUri.uri(Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId"))); } InAppWebViewGroupOptions options = InAppWebViewGroupOptions( diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 0ab1e1c6..0f98deb6 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse import 'package:diplomaticquarterapp/models/LiveCare/LiveCareScheduleClinicsListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_scheduling/schedule_clinic_card.dart'; @@ -196,11 +197,39 @@ class _clinic_listState extends State { getERAppointmentTime(GetERAppointmentFeesList getERAppointmentFeesList) { int languageID = projectViewModel.isArabic ? 1 : 2; + String errorMsg = ""; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); service.getERAppointmentTime(selectedClinicID, widget.isPharmacyLiveCare, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); + + // getERAppointmentFeesList.isCash = false; + // getERAppointmentFeesList.isInsured = true; + // getERAppointmentFeesList.isEligible = false; + + if (getERAppointmentFeesList.isCash!) { + showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); + } else { + if (getERAppointmentFeesList.isInsured! && getERAppointmentFeesList.isEligible!) { + showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); + } else { + if (getERAppointmentFeesList.isInsured! && !getERAppointmentFeesList.isEligible!) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash()}); + dialog.showAlertDialog(context); + } + } + // showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); @@ -208,6 +237,28 @@ class _clinic_listState extends State { }); } + void continueAsCash() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.convertPatientToCash(BASE_URL.contains("uat.") ? 15 : 12).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + startLiveCare(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } + showLiveCarePaymentDialog(GetERAppointmentFeesList getERAppointmentFeesList, int waitingTime) { navigateTo( context, @@ -322,15 +373,17 @@ class _clinic_listState extends State { String pharmaLiveCareQRCodeValue = widget.pharmacyLiveCareQRCode; Navigator.push( - context, - FadePage( - page: PaymentMethod( + context, + FadePage( + page: PaymentMethod( onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { setState(() {}); }, patientShare: num.parse(getERAppointmentFeesList.total!), isFromAdvancePayment: widget.isPharmacyLiveCare, - ))).then((value) { + ), + ), + ).then((value) { if (value != null) { selectedPaymentMethod = value[0]; print(value); @@ -413,28 +466,28 @@ class _clinic_listState extends State { service.applePayInsertRequest(applePayInsertRequest, localContext!).then((res) async { if (res["MessageStatus"] == 1) { await localContext!.read().initiateApplePayWithPayfort( - customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, - // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, - customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", - orderDescription: "LiveCare Payment", - orderAmount: double.parse(amount), - merchantReference: transID, - payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, - currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", - onFailed: (failureResult) async { - log("failureResult: ${failureResult.toString()}"); - GifLoaderDialogUtils.hideDialog(localContext!); - AppToast.showErrorToast(message: failureResult.toString()); - }, - onSuccess: (successResult) async { - GifLoaderDialogUtils.hideDialog(localContext!); - log("Payfort: ${successResult.responseMessage}"); - await localContext!.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); - checkPaymentStatus(appo); - }, - projectId: appo.projectID, - serviceTypeEnum: ServiceTypeEnum.appointmentPayment, - ); + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "LiveCare Payment", + orderAmount: double.parse(amount), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + log("failureResult: ${failureResult.toString()}"); + GifLoaderDialogUtils.hideDialog(localContext!); + AppToast.showErrorToast(message: failureResult.toString()); + }, + onSuccess: (successResult) async { + GifLoaderDialogUtils.hideDialog(localContext!); + log("Payfort: ${successResult.responseMessage}"); + await localContext!.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: "An error occurred while processing your request"); @@ -901,7 +954,8 @@ class _clinic_listState extends State { } Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { - Navigator.push(context, FadePage(page: SearchResults(doctorsList: docList, isLiveCareAppointment: false, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))); + Navigator.push(context, + FadePage(page: SearchResults(doctorsList: docList, isLiveCareAppointment: false, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: false))); } updateSelectedIndex(PatientERGetClinicsList patientERGetClinicsList) { diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 608943ac..b43d9823 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -19,6 +19,7 @@ import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_requ import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/login/login.dart'; import 'package:diplomaticquarterapp/pages/login/register_new.dart'; +import 'package:diplomaticquarterapp/pages/login/user-login-agreement-page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -41,18 +42,14 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; -import 'package:local_auth_ios/types/auth_messages_ios.dart'; +// import 'package:local_auth_ios/types/auth_messages_ios.dart'; class ConfirmLogin extends StatefulWidget { final Function? changePageViewIndex; final fromRegistration; final bool isDubai; - const ConfirmLogin({Key? key, - this.changePageViewIndex, - this.fromRegistration = false, - this.isDubai = false}) - : super(key: key); + const ConfirmLogin({Key? key, this.changePageViewIndex, this.fromRegistration = false, this.isDubai = false}) : super(key: key); @override _ConfirmLogin createState() => _ConfirmLogin(); @@ -64,8 +61,7 @@ class _ConfirmLogin extends State { var sharedPref = AppSharedPreferences(); bool authenticated = false; final authService = AuthProvider(); - PharmacyModuleViewModel pharmacyModuleViewModel = - locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); late int mobileNumber; String errorMsg = ''; SelectDeviceIMEIRES? user; @@ -95,10 +91,8 @@ class _ConfirmLogin extends State { int fingrePrintBefore = 0; - AuthenticatedUserObject authenticatedUserObject = - locator(); - AppointmentRateViewModel appointmentRateViewModel = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); + AppointmentRateViewModel appointmentRateViewModel = locator(); late ProjectViewModel projectViewModel; late ToDoCountProviderModel toDoProvider; @@ -145,35 +139,17 @@ class _ConfirmLogin extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - TranslationBase - .of(context) - .welcomeBack, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64), + TranslationBase.of(context).welcomeBack, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64), ), Text( user!.name!.toLowerCase().capitalizeFirstofEach, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w700, - color: Color(0xff2B353E), - height: 1, - letterSpacing: -1.44), + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xff2B353E), height: 1, letterSpacing: -1.44), ), SizedBox(height: 10), Text( - TranslationBase - .of(context) - .accountInfo, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64, - height: 25 / 16), + TranslationBase.of(context).accountInfo, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), ), Container( height: 72, @@ -192,48 +168,28 @@ class _ConfirmLogin extends State { mainAxisSize: MainAxisSize.min, children: [ Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - TranslationBase - .of(context) - .lastLoginAt - .toCamelCase, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64), + TranslationBase.of(context).lastLoginAt.toCamelCase, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64), ), Text( // user!.editedOn != null // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user!.editedOn!)) // : - user!.createdOn != null - ? DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - user!.createdOn!)) - : '--', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.48), + user!.createdOn != null ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user!.createdOn!)) : '--', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), ), ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - TranslationBase - .of(context) - .lastLoginWith - .toCamelCase, + TranslationBase.of(context).lastLoginWith.toCamelCase, style: TextStyle( fontSize: 10, fontWeight: FontWeight.w600, @@ -256,17 +212,8 @@ class _ConfirmLogin extends State { // user!.editedOn!), // false) // : - user!.createdOn != null - ? DateUtil.formatDateToTimeLang( - DateUtil.convertStringToDate( - user!.createdOn!), - false) - : '--', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff575757), - letterSpacing: -0.48), + user!.createdOn != null ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user!.createdOn!), false) : '--', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), ), ], ) @@ -274,21 +221,11 @@ class _ConfirmLogin extends State { ), ), Text( - TranslationBase - .of(context) - .pleaseVerify, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2E303A), - letterSpacing: -0.64), + TranslationBase.of(context).pleaseVerify, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), ), GridView( - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 13, - mainAxisSpacing: 9), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.only(top: 9), shrinkWrap: true, @@ -302,67 +239,40 @@ class _ConfirmLogin extends State { ], ) else - Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/habib-logo.png', - height: 90, - width: 90, - ), - SizedBox(height: 23), - this.onlySMSBox == false - ? Text( - TranslationBase - .of(context) - .verifyLoginWith, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64, - height: 25 / 16), - ) - : Text( - TranslationBase - .of(context) - .verifyFingerprint2, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64, - height: 25 / 16), - ), - SizedBox(height: 23), - Text( - TranslationBase - .of(context) - .pleaseVerify, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color(0xff2E303A), - letterSpacing: -0.64), - ), - GridView( - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 13, - mainAxisSpacing: 9), - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(top: 9), - shrinkWrap: true, - children: [ - if (onlySMSBox == false) getButton(3), - if (onlySMSBox == false) getButton(2), - getButton(1), - getButton(4), - ], - ), - ]), + Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Image.asset( + 'assets/images/habib-logo.png', + height: 90, + width: 90, + ), + SizedBox(height: 23), + this.onlySMSBox == false + ? Text( + TranslationBase.of(context).verifyLoginWith, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + ) + : Text( + TranslationBase.of(context).verifyFingerprint2, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + ), + SizedBox(height: 23), + Text( + TranslationBase.of(context).pleaseVerify, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + if (onlySMSBox == false) getButton(3), + if (onlySMSBox == false) getButton(2), + getButton(1), + getButton(4), + ], + ), + ]), ], ), ), @@ -370,13 +280,10 @@ class _ConfirmLogin extends State { height: 12, ), DefaultButton( - TranslationBase - .of(context) - .useAnotherAccount, - () { + TranslationBase.of(context).useAnotherAccount, + () { Navigator.of(context).pushNamed(LOGIN_TYPE); - projectViewModel.analytics.loginRegistration - .login_with_other_account(); + projectViewModel.analytics.loginRegistration.login_with_other_account(); }, ), ], @@ -387,13 +294,12 @@ class _ConfirmLogin extends State { Future _getAvailableBiometrics() async { final bool canAuthenticateWithBiometrics = await auth.canCheckBiometrics; - final bool canAuthenticate = - canAuthenticateWithBiometrics || await auth.isDeviceSupported(); + final bool canAuthenticate = canAuthenticateWithBiometrics || await auth.isDeviceSupported(); var availableBiometrics; try { availableBiometrics = await auth.getAvailableBiometrics(); - print(availableBiometrics); + // print(availableBiometrics); } on PlatformException catch (e) { AppToast.showErrorToast(message: e.message!); print(e); @@ -417,8 +323,7 @@ class _ConfirmLogin extends State { login_method = type; LoginRegistration.verificationMethod = type; // if(!widget.fromRegistration) - projectViewModel.analytics.loginRegistration - .login_verfication(forRegistration: widget.fromRegistration); + projectViewModel.analytics.loginRegistration.login_verfication(forRegistration: widget.fromRegistration); switch (type) { case 1: @@ -436,8 +341,7 @@ class _ConfirmLogin extends State { default: break; } - sharedPref.setInt(LAST_LOGIN, - this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); } loginWithSMS(type) { @@ -465,23 +369,22 @@ class _ConfirmLogin extends State { sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); authService .checkPatientAuthentication(request) - .then((value) => - { - GifLoaderDialogUtils.hideDialog(context), - if (value['isSMSSent']) - { - sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), - this.loginTokenID = value['LogInTokenID'], - sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), - // Future.delayed(Duration(seconds: 1), () { - this.sendActivationCode(type) - // }) - } - else - { - if (value['IsAuthenticated']) {this.checkActivationCode()} - } - }) + .then((value) => { + GifLoaderDialogUtils.hideDialog(context), + if (value['isSMSSent']) + { + sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), + this.loginTokenID = value['LogInTokenID'], + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), + // Future.delayed(Duration(seconds: 1), () { + this.sendActivationCode(type) + // }) + } + else + { + if (value['IsAuthenticated']) {this.checkActivationCode()} + } + }) .catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); @@ -494,8 +397,7 @@ class _ConfirmLogin extends State { GifLoaderDialogUtils.showMyDialog(context); if (healthId != null || widget.isDubai) { if (!widget.isDubai) { - request.dob = - dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); + request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); } request.healthId = healthId; request.isHijri = isHijri; @@ -532,11 +434,10 @@ class _ConfirmLogin extends State { context, type, this.mobileNumber, - (value) { + (value) { this.checkActivationCode(value: value); }, - () => - { + () => { Navigator.pop(context), }, ).displayDialog(context); @@ -552,11 +453,11 @@ class _ConfirmLogin extends State { stickyAuth: true, ), authMessages: [ - IOSAuthMessages( - cancelButton: 'cancel', - goToSettingsButton: 'settings', - goToSettingsDescription: 'Please set up your Touch ID.', - lockOut: 'Please reenable your Touch ID'), + // IOSAuthMessages( + // cancelButton: 'cancel', + // goToSettingsButton: 'settings', + // goToSettingsDescription: 'Please set up your Touch ID.', + // lockOut: 'Please reenable your Touch ID'), ], ); } on PlatformException catch (e) { @@ -612,28 +513,23 @@ class _ConfirmLogin extends State { setDefault() async { showLoader(true); - if (await sharedPref.getObject(IMEI_USER_DATA) != null) - user = SelectDeviceIMEIRES.fromJson( - await sharedPref.getObject(IMEI_USER_DATA)); + if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { isMoreOption = true; - this.registerd_data = await CheckPatientAuthenticationReq.fromJson( - await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); + this.registerd_data = await CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); } - this.mobileNumber = this.registerd_data != null - ? this.registerd_data.patientMobileNumber - : int.parse(this.user!.mobile!); + this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user!.mobile!); this.zipCode = this.registerd_data != null ? this.registerd_data.zipCode : this.user!.outSA == true - ? "971" - : "966"; + ? "971" + : "966"; this.patientOutSA = this.registerd_data != null ? this.registerd_data.zipCode == "966" - ? 0 - : 1 + ? 0 + : 1 : this.user!.outSA; if (this.registerd_data != null) { this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); @@ -643,9 +539,7 @@ class _ConfirmLogin extends State { if (nhic != null) { final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); - dob = nhic['IsHijri'] - ? nhic['DateOfBirth'] - : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); + dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); isHijri = nhic['IsHijri'] ? 1 : 0; healthId = nhic['HealthId']; @@ -654,8 +548,8 @@ class _ConfirmLogin extends State { this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null ? await sharedPref.getInt(LAST_LOGIN) : user != null - ? user!.logInType - : null; + ? user!.logInType + : null; showLoader(false); //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); @@ -668,34 +562,22 @@ class _ConfirmLogin extends State { request.deviceToken = this.deviceToken; request.projectOutSA = this.patientOutSA == true ? true : false; request.loginType = this.selectedOption; - request.oTPSendType = - type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; + request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; request.zipCode = this.zipCode; request.logInTokenID = this.loginTokenID ?? ""; if (this.registerd_data != null) { - request.searchType = this.registerd_data.searchType != null - ? this.registerd_data.searchType - : 1; - request.patientID = this.registerd_data.patientID != null - ? this.registerd_data.patientID - : 0; - request.patientIdentificationID = request.nationalID = - this.registerd_data.patientIdentificationID != null - ? this.registerd_data.patientIdentificationID - : '0'; + request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; + request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; + request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; request.dob = this.registerd_data.dob; request.isRegister = this.registerd_data.isRegister; } else { request.searchType = request.searchType != null ? request.searchType : 2; - request.patientID = - this.user!.patientID != null ? this.user!.patientID : 0; - request.nationalID = - request.nationalID != null ? request.nationalID : '0'; - request.patientIdentificationID = request.patientIdentificationID != null - ? request.patientIdentificationID - : '0'; + request.patientID = this.user!.patientID != null ? this.user!.patientID : 0; + request.nationalID = request.nationalID != null ? request.nationalID : '0'; + request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; request.isRegister = false; } request.deviceTypeID = request.searchType; @@ -716,40 +598,31 @@ class _ConfirmLogin extends State { authService .checkActivationCodeRegister(request, value) - .then((result) => - { - res = result, - if (result is Map) - { - result = CheckActivationCode.fromJson( - result as Map), - if (this.registerd_data != null && - this.registerd_data.isRegister == true) - { - // if(widget.isDubai ==false){ - widget.changePageViewIndex!(1), - // if(widget.isDubai ==false){ - - Navigator.popUntil( - context, - (route) => - Utils.route(route, equalsTo: RegisterNew)), - } - } - else - { - // Navigator.of(context).pop(), - GifLoaderDialogUtils.hideDialog(context), - Future.delayed(Duration(seconds: 1), () { - AppToast.showErrorToast(message: result); - }), - projectViewModel.analytics.loginRegistration - .login_fail(error: result), - projectViewModel.analytics.errorTracking.log( - 'otp_verification_at_confirm_login', - error: result), - } - }) + .then((result) => { + res = result, + if (result is Map) + { + result = CheckActivationCode.fromJson(result as Map), + if (this.registerd_data != null && this.registerd_data.isRegister == true) + { + // if(widget.isDubai ==false){ + widget.changePageViewIndex!(1), + // if(widget.isDubai ==false){ + + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), + } + } + else + { + // Navigator.of(context).pop(), + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: result); + }), + projectViewModel.analytics.loginRegistration.login_fail(error: result), + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result), + } + }) .catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); @@ -762,62 +635,56 @@ class _ConfirmLogin extends State { authService .checkActivationCode(request, value) .then((result) => { - res = result, - if (result is Map) - { - result = CheckActivationCode.fromJson(result as Map), - if(result.errorCode =='699'){ - //699 block run here - GifLoaderDialogUtils.hideDialog(context), - Future.delayed(Duration(seconds: 2), () { - AppToast.showErrorToast(message: result.errorEndUserMessage); - Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: Login)); + res = result, + if (result is Map) + { + result = CheckActivationCode.fromJson(result as Map), + if (result.errorCode == '699') + { + //699 block run here + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 2), () { + AppToast.showErrorToast(message: result.errorEndUserMessage); + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: Login)); + }) + } + else if (this.registerd_data != null && this.registerd_data.isRegister == true) + { + widget.changePageViewIndex!(1), + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), + } + else + { + sharedPref.remove(FAMILY_FILE), + result.list.isFamily = false, + userData = result.list, + sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), + //Remove o+ from here Added by Aamir + authenticatedUserObject.user = result.list, + projectViewModel.setPrivilege(privilegeList: res), + sharedPref.setObject(MAIN_USER, result.list), + sharedPref.setObject(USER_PROFILE, result.list), + loginTokenID = result.logInTokenID, + sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + sharedPref.setString(TOKEN, result.authenticationTokenID), + checkIfUserAgreedBefore(result), + projectViewModel.analytics.loginRegistration.login_successful(), + } + } + else + { + // Navigator.of(context).pop(), + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 1), () { + Navigator.of(context).pop(); + AppToast.showErrorToast(message: result, localContext: context); + startSMSService(tempType); + }), + + projectViewModel.analytics.loginRegistration.login_fail(error: result), + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result) + } }) - } - else if (this.registerd_data != null && - this.registerd_data.isRegister == true) - { - widget.changePageViewIndex!(1), - Navigator.popUntil( - context, - (route) => - Utils.route(route, equalsTo: RegisterNew)), - } - else - { - sharedPref.remove(FAMILY_FILE), - result.list.isFamily = false, - userData = result.list, - sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), - //Remove o+ from here Added by Aamir - authenticatedUserObject.user = result.list, - projectViewModel.setPrivilege(privilegeList: res), - sharedPref.setObject(MAIN_USER, result.list), - sharedPref.setObject(USER_PROFILE, result.list), - loginTokenID = result.logInTokenID, - sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), - sharedPref.setString(TOKEN, result.authenticationTokenID), - checkIfUserAgreedBefore(result), - projectViewModel.analytics.loginRegistration.login_successful(), - - } - } - else - { - // Navigator.of(context).pop(), - GifLoaderDialogUtils.hideDialog(context), - Future.delayed(Duration(seconds: 1), () { - Navigator.of(context).pop(); - AppToast.showErrorToast(message: result); - startSMSService(tempType); - }), - - projectViewModel.analytics.loginRegistration - .login_fail(error: result), - projectViewModel.analytics.errorTracking - .log('otp_verification_at_confirm_login', error: result) - } - }) .catchError((err) { GifLoaderDialogUtils.hideDialog(context); Future.delayed(Duration(seconds: 1), () { @@ -830,6 +697,33 @@ class _ConfirmLogin extends State { } checkIfUserAgreedBefore(CheckActivationCode result) { + // this.authService.checkIfUserAgreed().then((result) { + // if (result['IsPatientAlreadyAgreed']) { + // goToHome(); + // } else { + // this.authService.getUserAgreementContent().then((result) { + // GifLoaderDialogUtils.hideDialog(AppGlobal.context); + // Navigator.pushAndRemoveUntil( + // context, + // FadePage( + // page: UserLoginAgreementPage( + // userAgreementText: result['UserAgreementContent'], + // authenticatedUserObject: authenticatedUserObject, + // appointmentRateViewModel: appointmentRateViewModel, + // selectedOption: selectedOption, + // ), + // ), + // (r) => false); + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // }); + // } + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // }); + // if (result.isNeedUserAgreement == true) { //move to agreement page. // } else { @@ -851,25 +745,18 @@ class _ConfirmLogin extends State { print("Has Admission Request: $hasAdmissionRequest"); if (isAdmitted) { if (res['PatientAdmittedInformation'].length != 0) { - getAdmissionInfoResponseModel = - GetAdmissionInfoResponseModel.fromJson( - res['PatientAdmittedInformation'][0]); - projectViewModel.setInPatientProjectID( - res['PatientAdmittedInformation'][0]['ProjectID']); - projectViewModel - .setInPatientAdmissionInfo(getAdmissionInfoResponseModel); + getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(res['PatientAdmittedInformation'][0]); + projectViewModel.setInPatientProjectID(res['PatientAdmittedInformation'][0]['ProjectID']); + projectViewModel.setInPatientAdmissionInfo(getAdmissionInfoResponseModel); projectViewModel.setIsPatientAdmitted(true); } } if (hasAdmissionRequest) { if (res['MedicalInstruction'].length != 0) { - getAdmissionRequestInfoResponseModel = - GetAdmissionRequestInfoResponseModel.fromJson( - res['MedicalInstruction'][0]); - projectViewModel.setInPatientProjectID( - res['MedicalInstruction'][0]['ProjectID']); - projectViewModel.setInPatientAdmissionRequest( - getAdmissionRequestInfoResponseModel); + getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(res['MedicalInstruction'][0]); + // projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['ProjectID']); + projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['projectId']); + projectViewModel.setInPatientAdmissionRequest(getAdmissionRequestInfoResponseModel); projectViewModel.setPatientHasAdmissionRequest(true); } } @@ -878,10 +765,7 @@ class _ConfirmLogin extends State { } insertIMEI() { - authService - .insertDeviceImei(selectedOption) - .then((value) => {}) - .catchError((err) { + authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { print(err); }); } @@ -891,8 +775,7 @@ class _ConfirmLogin extends State { ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { if (res['MessageStatus'] == 1) { - toDoProvider.setState(res['AppointmentActiveNumber'], - res['AncillaryOrderListCount'], true, "0"); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); } else {} }).catchError((err) { @@ -909,44 +792,34 @@ class _ConfirmLogin extends State { // GifLoaderDialogUtils.hideDialog(context); getToDoCount(); + checkIfIsInPatient(); appointmentRateViewModel .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) - .then((value) => - { - GifLoaderDialogUtils.hideDialog(AppGlobal.context), - if (appointmentRateViewModel.isHaveAppointmentNotRate) - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: RateAppointmentDoctor(), - ), - (r) => false) - } - else - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: LandingPage(), - ), - (r) => false) - }, - insertIMEI() - }) + .then((value) => { + GifLoaderDialogUtils.hideDialog(AppGlobal.context), + if (appointmentRateViewModel.isHaveAppointmentNotRate) + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: RateAppointmentDoctor(), + ), + (r) => false) + } + else + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false) + }, + insertIMEI() + }) .catchError((err) { print(err); }); - - // getToDoCount(); - - // Navigator.pushAndRemoveUntil( - // context, - // FadePage( - // page: LandingPage(), - // ), - // (r) => false); - // insertIMEI(); } loading(flag) { @@ -956,26 +829,21 @@ class _ConfirmLogin extends State { } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = - (_flag == 3 && !checkIfBiometricAvailable(BiometricType.face) || - _flag == 2 && - !checkIfBiometricAvailable(BiometricType.fingerprint) && - _flag == 2 && - !checkIfBiometricAvailable(BiometricType.strong)); + bool isDisable = (_flag == 3 && !checkIfBiometricAvailable(BiometricType.face) || + _flag == 2 && !checkIfBiometricAvailable(BiometricType.fingerprint) && _flag == 2 && !checkIfBiometricAvailable(BiometricType.strong)); return InkWell( onTap: isDisable ? null : () { - if (_flag == 0) { - setState(() { - isMoreOption = true; - }); - } else { - authenticateUser(_flag, isActive: _loginIndex); - projectViewModel.analytics.loginRegistration.verify_otp_method( - forRegistration: widget.fromRegistration); - } - }, + if (_flag == 0) { + setState(() { + isMoreOption = true; + }); + } else { + authenticateUser(_flag, isActive: _loginIndex); + projectViewModel.analytics.loginRegistration.verify_otp_method(forRegistration: widget.fromRegistration); + } + }, child: Container( padding: EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), decoration: BoxDecoration( @@ -997,17 +865,8 @@ class _ConfirmLogin extends State { color: isDisable ? Color(0xff2B353E).withOpacity(0.7) : null, ), Text( - TranslationBase - .of(context) - .verifyThrough + " " + _title, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: isDisable - ? Color(0xff2B353E).withOpacity(0.7) - : Color(0xff2B353E), - letterSpacing: -0.48, - height: 20 / 16), + TranslationBase.of(context).verifyThrough + " " + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: isDisable ? Color(0xff2B353E).withOpacity(0.7) : Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), ), ], ), @@ -1019,49 +878,28 @@ class _ConfirmLogin extends State { Widget getButton(int flag) { switch (flag) { case 4: - return _loginOptionButton(TranslationBase - .of(context) - .verifyWhatsApp, - 'assets/images/new/verify_whatsapp.svg', flag, null); + return _loginOptionButton(TranslationBase.of(context).verifyWhatsApp, 'assets/images/new/verify_whatsapp.svg', flag, null); break; case 1: - return _loginOptionButton(TranslationBase - .of(context) - .verifySMS, - 'assets/images/new/verify_sms.svg', flag, null); + return _loginOptionButton(TranslationBase.of(context).verifySMS, 'assets/images/new/verify_sms.svg', flag, null); break; case 2: - return _loginOptionButton( - TranslationBase - .of(context) - .verifyFingerprint, - 'assets/images/new/verify_thumb.svg', - flag, - BiometricType.fingerprint.index); + return _loginOptionButton(TranslationBase.of(context).verifyFingerprint, 'assets/images/new/verify_thumb.svg', flag, BiometricType.fingerprint.index); break; case 3: - return _loginOptionButton( - TranslationBase - .of(context) - .verifyFaceID, - 'assets/images/new/verify_face.svg', - flag, - BiometricType.face.index); + return _loginOptionButton(TranslationBase.of(context).verifyFaceID, 'assets/images/new/verify_face.svg', flag, BiometricType.face.index); break; default: return InkWell( - onTap: () => - { + onTap: () => { setState(() { isMoreOption = true; }) }, child: RoundedContainer( height: 150, - backgroundColor: BiometricType.fingerprint.index == 1 - ? Colors.white - : Colors.white.withOpacity(.7), + backgroundColor: BiometricType.fingerprint.index == 1 ? Colors.white : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( @@ -1075,17 +913,12 @@ class _ConfirmLogin extends State { ), projectViewModel.isArabic ? SizedBox( - height: 15, - ) + height: 15, + ) : SizedBox( - height: 20, - ), - Texts(TranslationBase - .of(context) - .moreVerification, - fontSize: SizeConfig.textMultiplier! * 1.8, - textAlign: TextAlign.center, - color: Colors.black) + height: 20, + ), + Texts(TranslationBase.of(context).moreVerification, fontSize: SizeConfig.textMultiplier! * 1.8, textAlign: TextAlign.center, color: Colors.black) ], ), ), @@ -1097,35 +930,24 @@ class _ConfirmLogin extends State { getType(type, context) { switch (type) { case 1: - return TranslationBase - .of(context) - .verifySMS; + return TranslationBase.of(context).verifySMS; break; case 2: - return TranslationBase - .of(context) - .verifyFingerprint; + return TranslationBase.of(context).verifyFingerprint; break; case 3: - return TranslationBase - .of(context) - .verifyFaceID; + return TranslationBase.of(context).verifyFaceID; break; case 4: - return TranslationBase - .of(context) - .verifyWhatsApp; + return TranslationBase.of(context).verifyWhatsApp; break; default: - return TranslationBase - .of(context) - .verifySMS; + return TranslationBase.of(context).verifySMS; break; } } bool checkIfBiometricAvailable(BiometricType biometricType) { - print(biometricType); bool isAvailable = false; if (_availableBiometrics != null) { for (var i = 0; i < _availableBiometrics.length; i++) { diff --git a/lib/pages/login/forgot-password.dart b/lib/pages/login/forgot-password.dart index 7207e602..529d0b8f 100644 --- a/lib/pages/login/forgot-password.dart +++ b/lib/pages/login/forgot-password.dart @@ -1,4 +1,6 @@ +import 'package:cloudflare_turnstile/cloudflare_turnstile.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -27,6 +29,23 @@ class _ForgotPassword extends State { String mobileNo = ""; var con; + final TurnstileController _controller = TurnstileController(); + final TurnstileOptions _options = TurnstileOptions( + size: TurnstileSize.normal, + theme: TurnstileTheme.light, + refreshExpired: TurnstileRefreshExpired.manual, + language: 'en', + retryAutomatically: false, + ); + + String? _token; + + @override + void dispose() { + super.dispose(); + _controller.dispose(); + } + @override Widget build(BuildContext context) { con = context; @@ -66,6 +85,25 @@ class _ForgotPassword extends State { countryCode = value; }); }), + const SizedBox(height: 12.0), + CloudFlareTurnstile( + siteKey: '0x4AAAAAAAkmbvEy63pcxBBt', + baseUrl: BASE_URL, + options: _options, + controller: _controller, + onTokenRecived: (token) { + setState(() { + print("Cloudflare token: $token"); + _token = token; + }); + }, + onTokenExpired: () {}, + mode: TurnstileMode.managed, + errorBuilder: (context, error) { + return Text(error.message); + }, + ), + const SizedBox(height: 48.0), ], ), ), diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 18ed5440..beb047f5 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -151,7 +151,7 @@ class _Login extends State { TranslationBase.of(context).login, () { if (isButtonDisabled) { - AppToast.showErrorToast(message: "National ID can only contain numbers"); + AppToast.showErrorToast(message: TranslationBase.of(context).incorrectNationalId, localContext: context); } else { this.startLogin(); } @@ -386,6 +386,7 @@ class _Login extends State { // ), // (r) => false); getToDoCount(); + checkIfIsInPatient(); appointmentRateViewModel .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) .then((value) => { @@ -462,7 +463,7 @@ class _Login extends State { GetAdmissionRequestInfoResponseModel.fromJson( res['MedicalInstruction'][0]); projectViewModel.setInPatientProjectID( - res['MedicalInstruction'][0]['ProjectID']); + res['MedicalInstruction'][0]['projectId']); projectViewModel.setInPatientAdmissionRequest( getAdmissionRequestInfoResponseModel); projectViewModel.setPatientHasAdmissionRequest(true); diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart index e2b7db20..e3d2f020 100644 --- a/lib/pages/login/register-info.dart +++ b/lib/pages/login/register-info.dart @@ -450,15 +450,15 @@ class _RegisterInfo extends State { else request = getTempUserRequest(); - GifLoaderDialogUtils.showMyDialog(context); + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); dynamic res; this .authService .registerUser(request) - .then((result) => { - GifLoaderDialogUtils.hideDialog(context), + .then((result) async => { if (result is String) { + GifLoaderDialogUtils.hideDialog(context), new ConfirmDialog( context: context, confirmMessage: result, @@ -480,14 +480,14 @@ class _RegisterInfo extends State { sharedPref.remove(FAMILY_FILE), result.list.isFamily = false, - sharedPref.setString(BLOOD_TYPE, result.patientBloodType), + await sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), authenticatedUserObject.user = result.list, projectViewModel.setPrivilege(privilegeList: res), - sharedPref.setObject(MAIN_USER, result.list), - sharedPref.setObject(USER_PROFILE, result.list), + await sharedPref.setObject(MAIN_USER, result.list), + await sharedPref.setObject(USER_PROFILE, result.list), - sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), - sharedPref.setString(TOKEN, result.authenticationTokenID), + await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + await sharedPref.setString(TOKEN, result.authenticationTokenID), AppToast.showSuccessToast(message: TranslationBase.of(context).successRegister), checkIfUserAgreedBefore(result), projectViewModel.analytics.loginRegistration.registration_confirmation() @@ -695,6 +695,7 @@ class _RegisterInfo extends State { insertIMEI() async { var selectedOption = await sharedPref.getInt(LAST_LOGIN); authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); }); } @@ -705,45 +706,70 @@ class _RegisterInfo extends State { projectViewModel.isLogin = true; projectViewModel.user = authenticatedUserObject.user; await authenticatedUserObject.getUser(getUser: true); - int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; - appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) { - getToDoCount(); - GifLoaderDialogUtils.hideDialog(AppGlobal.context); - if (appointmentRateViewModel.isHaveAppointmentNotRate) { - Navigator.pushAndRemoveUntil( + getToDoCount(); + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).validInsurance, + okText: TranslationBase.of(context).yes, + cancelText: TranslationBase.of(context).no, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + Navigator.pushAndRemoveUntil( context, - FadePage( - page: RateAppointmentDoctor(isFromRegistration: true), - ), - (r) => false); - } else { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: TranslationBase.of(context).validInsurance, - okText: TranslationBase.of(context).yes, - cancelText: TranslationBase.of(context).no, - okFunction: () { - ConfirmDialog.closeAlertDialog(context); - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) => LandingPage()), + MaterialPageRoute(builder: (context) => LandingPage()), (Route route) => false, - ); - Navigator.push(context, FadePage(page: InsuranceUpdate())); - }, - cancelFunction: () { - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) => LandingPage()), - (Route route) => false, - ); - }); - dialog.showAlertDialog(context); - } - }).catchError((err) { - print(err); - //GifLoaderDialogUtils.hideDialog(context); - }); + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + cancelFunction: () { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + }); + dialog.showAlertDialog(context); + + // int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + // appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) { + // getToDoCount(); + // GifLoaderDialogUtils.hideDialog(AppGlobal.context); + // if (appointmentRateViewModel.isHaveAppointmentNotRate) { + // Navigator.pushAndRemoveUntil( + // context, + // FadePage( + // page: RateAppointmentDoctor(isFromRegistration: true), + // ), + // (r) => false); + // } else { + // ConfirmDialog dialog = new ConfirmDialog( + // context: context, + // confirmMessage: TranslationBase.of(context).validInsurance, + // okText: TranslationBase.of(context).yes, + // cancelText: TranslationBase.of(context).no, + // okFunction: () { + // ConfirmDialog.closeAlertDialog(context); + // Navigator.pushAndRemoveUntil( + // context, + // MaterialPageRoute(builder: (context) => LandingPage()), + // (Route route) => false, + // ); + // Navigator.push(context, FadePage(page: InsuranceUpdate())); + // }, + // cancelFunction: () { + // Navigator.pushAndRemoveUntil( + // context, + // MaterialPageRoute(builder: (context) => LandingPage()), + // (Route route) => false, + // ); + // }); + // dialog.showAlertDialog(context); + // } + // }).catchError((err) { + // print(err); + // //GifLoaderDialogUtils.hideDialog(context); + // }); // SMSOTP.showLoadingDialog(context, false), } diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index a010150d..2dd32163 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; @@ -25,6 +26,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:intl/intl.dart' as intl; +import 'package:provider/provider.dart'; class Register extends StatefulWidget { final Function? changePageViewIndex; @@ -297,8 +299,9 @@ class _Register extends State { } checkPatientForRegisteration(request) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); - this.authService.checkPatientForRegisteration(request).then((response) => {checkUserStatus(response, request)}).catchError((err) { + this.authService.checkPatientForRegisteration(request, languageID).then((response) => {checkUserStatus(response, request)}).catchError((err) { GifLoaderDialogUtils.hideDialog(context); ConfirmDialog dialog = new ConfirmDialog( context: context, diff --git a/lib/pages/login/user-login-agreement-page.dart b/lib/pages/login/user-login-agreement-page.dart new file mode 100644 index 00000000..f01a0c96 --- /dev/null +++ b/lib/pages/login/user-login-agreement-page.dart @@ -0,0 +1,215 @@ +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/TermsConditionsViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.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:flutter_html/flutter_html.dart'; +import 'package:provider/provider.dart'; + +class UserLoginAgreementPage extends StatefulWidget { + final String userAgreementText; + final AuthenticatedUserObject authenticatedUserObject; + final AppointmentRateViewModel appointmentRateViewModel; + final int selectedOption; + + UserLoginAgreementPage({required this.userAgreementText, required this.authenticatedUserObject, required this.appointmentRateViewModel, required this.selectedOption}); + + @override + State createState() => _UserLoginAgreementPageState(); +} + +class _UserLoginAgreementPageState extends State { + late ProjectViewModel projectViewModel; + late ToDoCountProviderModel toDoProvider; + final authService = AuthProvider(); + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); + return BaseView( + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).userAgreement, + body: Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + child: Html( + data: widget.userAgreementText, + ), + ), + ), + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + // color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Text( + TranslationBase.of(context).continueAgreeTerms, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + addUsageAgreement(); + }, + child: Text(TranslationBase.of(context).acceptLbl.toUpperCase(), + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + )), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false); + }, + child: Text(TranslationBase.of(context).declineLbl.toUpperCase(), style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } + + addUsageAgreement() { + GifLoaderDialogUtils.showMyDialog(context); + this.authService.addUserAgreementContent().then((result) { + goToHome(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + goToHome() async { + widget.authenticatedUserObject.isLogin = true; + widget.appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + projectViewModel.user = widget.authenticatedUserObject.user; + await widget.authenticatedUserObject.getUser(getUser: true); + + // GifLoaderDialogUtils.hideDialog(context); + getToDoCount(); + widget.appointmentRateViewModel + .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) + .then((value) => { + GifLoaderDialogUtils.hideDialog(context), + if (widget.appointmentRateViewModel.isHaveAppointmentNotRate) + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: RateAppointmentDoctor(), + ), + (r) => false) + } + else + { + GifLoaderDialogUtils.hideDialog(context), + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false) + }, + insertIMEI() + }) + .catchError((err) { + print(err); + }); + } + + insertIMEI() { + authService.insertDeviceImei(widget.selectedOption).then((value) => {}).catchError((err) { + print(err); + }); + } + + getToDoCount() { + toDoProvider.setState(0, 0, true, "0"); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); + } else {} + }).catchError((err) { + print(err); + }); + } +} diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart index 1081ef52..ab032541 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -40,6 +40,7 @@ class AskDoctorPage extends StatelessWidget { Widget _appointmentExpandableList(List _patientDoctorAppointmentList, model) { return ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), padding: EdgeInsets.only(top: 12), separatorBuilder: (context, index) { diff --git a/lib/pages/medical/balance/confirm_payment_page.dart b/lib/pages/medical/balance/confirm_payment_page.dart index 8b567556..da9570f2 100644 --- a/lib/pages/medical/balance/confirm_payment_page.dart +++ b/lib/pages/medical/balance/confirm_payment_page.dart @@ -329,6 +329,7 @@ class _ConfirmPaymentPageState extends State { payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, currency: projectViewModel.authenticatedUserObject.user.outSA == 1 ? "AED" : "SAR", onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); log("failureResult: ${failureResult.toString()}"); AppToast.showErrorToast(message: failureResult.toString()); }, @@ -528,7 +529,6 @@ class _ConfirmPaymentPageState extends State { addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, AppGlobal.context).then((res) { - print(res); GifLoaderDialogUtils.hideDialog(AppGlobal.context); navigateToHome(AppGlobal.context); }).catchError((err) { diff --git a/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart b/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart index ce69e8c0..de22c7af 100644 --- a/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart +++ b/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.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'; @@ -363,11 +364,11 @@ class _ConfirmSMSDialogState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/medical/balance/new_text_Field.dart b/lib/pages/medical/balance/new_text_Field.dart index b00e4274..fb9d8bed 100644 --- a/lib/pages/medical/balance/new_text_Field.dart +++ b/lib/pages/medical/balance/new_text_Field.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -184,7 +185,8 @@ class _NewTextFieldsState extends State { autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + // style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ FilteringTextInputFormatter.digitsOnly, @@ -194,9 +196,9 @@ class _NewTextFieldsState extends State { decoration: InputDecoration( labelText: widget.hintText, counterText: widget.counterText, - labelStyle: TextStyle(color: Theme.of(context).textTheme.bodyText1!.color), - errorBorder: OutlineInputBorder(borderSide: BorderSide(color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), - focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), + labelStyle: TextStyle(color: Colors.black), + errorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), + focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), enabledBorder: OutlineInputBorder( diff --git a/lib/pages/medical/labs/laboratory_result_page.dart b/lib/pages/medical/labs/laboratory_result_page.dart index 698e34d5..69f4b10e 100644 --- a/lib/pages/medical/labs/laboratory_result_page.dart +++ b/lib/pages/medical/labs/laboratory_result_page.dart @@ -53,6 +53,7 @@ class _LaboratoryResultPageState extends State { child: Column( children: [ ListView.builder( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), shrinkWrap: true, padding: EdgeInsets.only(bottom: 12), diff --git a/lib/pages/medical/labs/labs_home_page.dart b/lib/pages/medical/labs/labs_home_page.dart index b78617f3..7998b558 100644 --- a/lib/pages/medical/labs/labs_home_page.dart +++ b/lib/pages/medical/labs/labs_home_page.dart @@ -17,7 +17,7 @@ import 'package:provider/provider.dart'; import 'laboratory_result_page.dart'; class LabsHomePage extends StatelessWidget { - List imagesInfo =[]; + List imagesInfo = []; @override Widget build(BuildContext context) { @@ -50,6 +50,7 @@ class LabsHomePage extends StatelessWidget { child: FractionallySizedBox( widthFactor: 1.0, child: ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), padding: EdgeInsets.only(top: 12), separatorBuilder: (context, index) { diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart index 58f1e7d6..717037f2 100644 --- a/lib/pages/medical/prescriptions/prescription_items_page.dart +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -61,9 +61,11 @@ class PrescriptionItemsPage extends StatelessWidget { prescriptions.name!, DateUtil.convertStringToDate(prescriptions.appointmentDate!), DateUtil.formatDateToTime( - model.prescriptionReportEnhList.length > 0 || model.prescriptionReportListINP.length > 0 ? DateUtil.convertStringToDate( - model.prescriptionReportEnhList.length > 0 ? model.prescriptionReportEnhList[0].orderDate! : model.prescriptionReportListINP[0].orderDate!, - ) : DateTime.now(), + model.prescriptionReportEnhList.length > 0 || model.prescriptionReportListINP.length > 0 + ? DateUtil.convertStringToDate( + model.prescriptionReportEnhList.length > 0 ? model.prescriptionReportEnhList[0].orderDate! : model.prescriptionReportListINP[0].orderDate!, + ) + : DateTime.now(), ), prescriptions.nationalityFlagURL ?? "", prescriptions.doctorRate, @@ -433,7 +435,10 @@ class PrescriptionItemsPage extends StatelessWidget { doctorName: prescriptions.doctorName!, doctorID: prescriptions.doctorID!, mes: TranslationBase.of(context).sendSuc, - projectID: prescriptions.projectID!); + projectID: prescriptions.projectID!, + isInOutPatient: prescriptions.isInOutPatient! + + ); }, ), ); diff --git a/lib/pages/medical/prescriptions/prescriptions_page.dart b/lib/pages/medical/prescriptions/prescriptions_page.dart index 0c24c66f..e550e1b0 100644 --- a/lib/pages/medical/prescriptions/prescriptions_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_page.dart @@ -26,6 +26,7 @@ class PrescriptionsPage extends StatelessWidget { return AppScaffold( baseViewModel: prescriptionsViewModel, body: ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), padding: EdgeInsets.only(top: 12), separatorBuilder: (context, index) { diff --git a/lib/pages/medical/radiology/radiology_home_page.dart b/lib/pages/medical/radiology/radiology_home_page.dart index 09e443e5..fb60d5da 100644 --- a/lib/pages/medical/radiology/radiology_home_page.dart +++ b/lib/pages/medical/radiology/radiology_home_page.dart @@ -54,6 +54,7 @@ class RadiologyHomePage extends StatelessWidget { child: FractionallySizedBox( widthFactor: 1.0, child: ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), padding: EdgeInsets.only(top: 12), separatorBuilder: (context, index) { diff --git a/lib/pages/medical/sickleave_workplace_update_page.dart b/lib/pages/medical/sickleave_workplace_update_page.dart index 0e555bab..ec7991cb 100644 --- a/lib/pages/medical/sickleave_workplace_update_page.dart +++ b/lib/pages/medical/sickleave_workplace_update_page.dart @@ -25,6 +25,10 @@ class WorkplaceUpdatePage extends StatefulWidget { class _WorkplaceUpdatePageState extends State { TextEditingController workplaceName = new TextEditingController(); + + TextEditingController workplaceNameAr = new TextEditingController(); + TextEditingController occupationNameEn = new TextEditingController(); + TextEditingController occupationNameAr = new TextEditingController(); bool? _isButtonDisabled; ProjectViewModel? projectViewModel; @@ -66,7 +70,14 @@ class _WorkplaceUpdatePageState extends State { ), ), mHeight(8), - inputWidget(TranslationBase.of(context).workplaceName, "", workplaceName), + // inputWidget(TranslationBase.of(context).workplaceName, "", workplaceName), + inputWidget(TranslationBase.of(context).workplaceName, "", workplaceName, FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).workplaceNameAr, "", workplaceNameAr, FilteringTextInputFormatter.allow(RegExp("[ء-ي ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).occupationNameEn, "", occupationNameEn, FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).occupationNameAr, "", occupationNameAr, FilteringTextInputFormatter.allow(RegExp("[ء-ي ]"))), ], ), ), @@ -83,7 +94,7 @@ class _WorkplaceUpdatePageState extends State { height: 50, elevation: 0, color: CustomColors.accentColor, - disabledColor:Colors.grey.withOpacity(0.25), + disabledColor: Colors.grey.withOpacity(0.25), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), child: Text( TranslationBase.of(context).submit, @@ -94,10 +105,12 @@ class _WorkplaceUpdatePageState extends State { ), ), onPressed: () { - if (_isButtonDisabled == false) + // if (_isButtonDisabled == false) + if (workplaceNameAr.text.isNotEmpty && occupationNameAr.text.isNotEmpty) + // AppToast.showSuccessToast(message: "API Called"); updateWorkplaceNameDialog(); else - AppToast.showErrorToast(message: TranslationBase.of(context).enterWorkplaceName); + AppToast.showErrorToast(message: TranslationBase.of(context).enterDetailBelow); }, ), ), @@ -109,7 +122,8 @@ class _WorkplaceUpdatePageState extends State { ); } - Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, TextInputFormatter inputFormatter, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + // Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) { return Container( padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), alignment: Alignment.center, @@ -145,7 +159,8 @@ class _WorkplaceUpdatePageState extends State { keyboardType: TextInputType.name, controller: _controller, inputFormatters: [ - projectViewModel!.isArabic ? FilteringTextInputFormatter.allow(RegExp("[ء-ي ]")) : FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]")), + // projectViewModel!.isArabic ? FilteringTextInputFormatter.allow(RegExp("[ء-ي ]")) : FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]")), + inputFormatter ], onChanged: (value) => {_onPassportTextChanged(value)}, style: TextStyle( @@ -207,8 +222,8 @@ class _WorkplaceUpdatePageState extends State { } updateWorkplaceNameDialog() { - var messageEn = "The workplace name you entered is: " + workplaceName.text + ". Please confirm!"; - var messageAr = "اسم مكان العمل الذي أدخلته هو: " + workplaceName.text + ". يرجى تأكيد!"; + var messageEn = "The workplace name you entered is: " + workplaceNameAr.text + ". Please confirm!"; + var messageAr = "اسم مكان العمل الذي أدخلته هو: " + workplaceNameAr.text + ". يرجى تأكيد!"; ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: projectViewModel!.isArabic ? messageAr : messageEn, @@ -226,9 +241,10 @@ class _WorkplaceUpdatePageState extends State { LabsService service = new LabsService(); GifLoaderDialogUtils.showMyDialog(context); - service - .updateWorkplaceName(projectViewModel!.isArabic ? "-" : workplaceName.text, projectViewModel!.isArabic ? workplaceName.text : "-", widget.requestNumber, widget.setupID, widget.projectID) - .then((res) { + service.updateWorkplaceName(workplaceName.text, workplaceNameAr.text, occupationNameEn.text, occupationNameAr.text, widget.requestNumber, widget.setupID, widget.projectID).then((res) { + // service + // .updateWorkplaceName(projectViewModel!.isArabic ? "-" : workplaceName.text, projectViewModel!.isArabic ? workplaceName.text : "-", widget.requestNumber, widget.setupID, widget.projectID) + // .then((res) { GifLoaderDialogUtils.hideDialog(context); Navigator.of(context).pop(true); }).catchError((err) { diff --git a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart index 0e356b78..432707ce 100644 --- a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart @@ -216,7 +216,7 @@ class _DistanceTrackerState extends State with SingleTickerProv (element) { weeklyTimeSeriesData.add( TimeSeriesSales2( - DateUtil.convertStringToDate(element.machineDate!), + DateUtil.convertStringToDate(element.machineDate ?? DateUtil.convertDateToString(DateTime.now())), element.value != null ? (element.value!.toDouble() / 1000) : 0.0, ), ); @@ -501,7 +501,7 @@ class _DistanceTrackerState extends State with SingleTickerProv children: [ Utils.tableColumnValue( '${DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(step.machineDate!), + DateUtil.convertStringToDate(step.machineDate ?? DateUtil.convertDateToString(DateTime.now())), )} ', isCapitable: false, mProjectViewModel: projectViewModel), diff --git a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart index fcd87cfd..a9a19945 100644 --- a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart @@ -212,7 +212,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt (element) { weeklyTimeSeriesData.add( TimeSeriesSales2( - DateUtil.convertStringToDate(element.machineDate!), + DateUtil.convertStringToDate(element.machineDate ?? DateUtil.convertDateToString(DateTime.now())), element.value != null ? element.value!.toDouble() : 0.0, ), ); @@ -527,7 +527,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt children: [ Utils.tableColumnValue( '${DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(step.machineDate!), + DateUtil.convertStringToDate(step.machineDate ?? DateUtil.convertDateToString(DateTime.now())), )} ', isCapitable: false, mProjectViewModel: projectViewModel), diff --git a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart index e6ec5c9a..6d6fdf4f 100644 --- a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart +++ b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart @@ -34,7 +34,7 @@ class _syncHealthDataButtonState extends State { int MedCategoryID = 0; - HealthFactory health = HealthFactory(); + // HealthFactory health = HealthFactory(); List types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING]; @override @@ -48,29 +48,29 @@ class _syncHealthDataButtonState extends State { } checkPermissions() async { - if (Platform.isAndroid) { - if (await PermissionService.isHealthDataPermissionEnabled()) { - await health.requestAuthorization(types).then((value) { - if (value) { - readAll(); - } - }); - } else { - Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async { - await health.requestAuthorization(types).then((value) { - if (value) { - readAll(); - } - }); - }); - } - } else { - await health.requestAuthorization(types).then((value) { - if (value) { - readAll(); - } - }); - } + // if (Platform.isAndroid) { + // if (await PermissionService.isHealthDataPermissionEnabled()) { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // } else { + // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // }); + // } + // } else { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // } } void readAll() async { @@ -83,13 +83,13 @@ class _syncHealthDataButtonState extends State { DateTime startDate = DateTime.now().subtract(new Duration(days: 30)); try { - List healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types); - _healthDataList.addAll(healthData); + // List healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types); + // _healthDataList.addAll(healthData); } catch (e) { print("Caught exception in getHealthDataFromTypes: $e"); } - _healthDataList = HealthFactory.removeDuplicates(_healthDataList); + // _healthDataList = HealthFactory.removeDuplicates(_healthDataList); _healthDataList.forEach((x) { if (x.type == HealthDataType.STEPS) { diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index 1878a658..29161b50 100644 --- a/lib/pages/paymentService/payment_service.dart +++ b/lib/pages/paymentService/payment_service.dart @@ -71,9 +71,9 @@ class PaymentService extends StatelessWidget { projectViewModel!.analytics.advancePayments.payment_services(service_type: 'payment service'); }, child: MedicalProfileItem( - title: TranslationBase.of(context).payment, + title: TranslationBase.of(context).onlinePayment, imagePath: 'assets/images/new-design/online_payment_icon.png', - subTitle: TranslationBase.of(context).paymentOnline, + subTitle: TranslationBase.of(context).onlinePaymentSubtitle, isPngImage: true, width: 65.0, height: 55.0, @@ -182,19 +182,25 @@ class PaymentService extends StatelessWidget { ClinicListService service = new ClinicListService(); GifLoaderDialogUtils.showMyDialog(context); service - .getInPatientAdvancePaymentRequests(projectViewModel.inPatientProjectID, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, - projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, context) + .getInPatientAdvancePaymentRequests( + projectViewModel.inPatientProjectID, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isArabic ? 1 : 2, + context) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["MessageStatus"] == 1) { if (res['responseInpatient'] != null) { inPatientAdvanceResponseModel = InPatientAdvanceResponseModel.fromJson(res["responseInpatient"]); - Navigator.push(context, FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); } else { AppToast.showErrorToast(message: TranslationBase.of(context).noData); } } else { - Navigator.push(context, FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/rateAppointment/rate_appointment_clinic.dart b/lib/pages/rateAppointment/rate_appointment_clinic.dart index 44484373..4dbc3edd 100644 --- a/lib/pages/rateAppointment/rate_appointment_clinic.dart +++ b/lib/pages/rateAppointment/rate_appointment_clinic.dart @@ -75,7 +75,7 @@ class _RateAppointmentClinicState extends State { style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), ), Text( - model.appointmentDetails.startTime.toString().substring(0, 5), + model.appointmentDetails.startTime != "" ? model.appointmentDetails.startTime.toString().substring(0, 5) : "", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), ), ], diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 99131534..2b039701 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -34,7 +34,7 @@ class DoctorsListService extends BaseService { String? tokenID; List selectedBodyPartList = []; - Future getDoctorsList(int clinicID, int projectID, bool isNearest, int languageID, BuildContext context, {doctorId, doctorName, isContinueDentalPlan = false}) async { + Future getDoctorsList(int clinicID, int projectID, bool isNearest, int languageID, BuildContext? context, {doctorId, doctorName, isContinueDentalPlan = false}) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -92,8 +92,8 @@ class DoctorsListService extends BaseService { Future getDoctorsListByName(String docName, int languageID, BuildContext context) async { Map request; - late double lat; - late double long; + late double lat = 0.0; + late double long = 0.0; if (await this.sharedPref.getObject(USER_PROFILE) != null) { var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); @@ -334,8 +334,60 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future insertWalkInAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + Request req = appGlobal.getPublicRequest(); + request = { + "IsForLiveCare": false, + "ProjectID": projectID, + "ClinicID": clinicID, + "DoctorID": docID, + "StartTime": selectedTime, + "SelectedTime": selectedTime, + "EndTime": selectedTime, + "InitialSlotDuration": initialSlotDuration, + "StrAppointmentDate": selectedDate, + "IsVirtual": false, + "DeviceType": Platform.isIOS ? 'iOS' : 'Android', + "BookedBy": 102, + "VisitType": 1, + "VisitFor": 1, + "GenderID": authUser.gender, + "Age": authUser.age != null ? authUser.age : 0, + "VersionID": req.VersionID, + "Channel": req.Channel, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + + dynamic localRes; + try { + await baseAppClient.post(INSERT_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } catch (e) { + return Future.error(e); + } + } + Future insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context, - [String? procedureID, num? testTypeEnum, num? testProcedureEnum, ProjectViewModel? projectViewModel]) async { + [String? procedureID, num? testTypeEnum, num? testProcedureEnum, ProjectViewModel? projectViewModel, int? invoiceNumber, int? lineItemNo, String? invoiceNoVP]) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -374,7 +426,11 @@ class DoctorsListService extends BaseService { "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, "PatientTypeID": authUser.patientType, - "PatientType": authUser.patientType + "PatientType": authUser.patientType, + "InvoiceNo": invoiceNumber, + "InvoiceNo_VP": invoiceNoVP, + "LineItemNo": lineItemNo, + // "TokenID":"@dm!n" }; if (clinicID == 253) { @@ -509,6 +565,26 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future checkPatientHasDermaPackage(int patientID, int clinicID, int projectID, int doctorID, int languageID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = {"PatientID": patientID, "ClinicID": clinicID, "ProjectID": projectID, "LanguageID": languageID}; + //request = { "PatientID":4768732, "ClinicID":1, "ProjectID": 15, "LanguageID": languageID, "TokenID":"@dm!n" }; + + dynamic localRes; + + await baseAppClient.post(CHECK_PATIENT_DERMA_PACKAGE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getLiveCareAppointmentPatientShare(String appoID, int clinicID, int projectID, int languageID, BuildContext context) async { Map request; @@ -615,6 +691,32 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future getPatientShareForWalkInAppointment(int clinicID, int projectID, int doctorID) async { + Map request; + request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID}; + dynamic localRes; + await baseAppClient.post(GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future canPayForWalkInAppointment(int clinicID, int projectID, int doctorID) async { + Map request; + request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID, "StartTime": "12:00", "EndTime": "12:00"}; + dynamic localRes; + await baseAppClient.post(CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + Future getPatientAppointmentHistory(bool isActiveAppointment, int languageID, BuildContext context, {bool isForCOC = false, isForUpcomming = false, IsForArrived = false}) async { Map request; @@ -1428,12 +1530,12 @@ class DoctorsListService extends BaseService { Request req = appGlobal.getPublicRequest(); request = { - "VersionID": req.VersionID, - "Channel": req.Channel, - "IPAdress": req.IPAdress, - "generalid": req.generalid, - "PatientOutSA": authUser.outSA, - "PatientTypeID": authUser.patientType, + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "IPAdress": req.IPAdress, + // "generalid": req.generalid, + // "PatientOutSA": authUser.outSA, + // "PatientTypeID": authUser.patientType, "LanguageID": 1, "ERAdvanceAmount": { "ProjectId": projectID, @@ -1535,10 +1637,10 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future sendCheckinNfcRequest(int appointmentNo, String nfcCode, int projectId, int checkInBy, BuildContext context) async { + Future sendCheckinNfcRequest(int appointmentNo, String nfcCode, int projectId, int checkInBy, int clinicID, BuildContext context) async { Map request; - request = {"AppointmentNo": appointmentNo, "NFC_Code": nfcCode, "ProjectID": projectId, "CheckinBy": checkInBy}; + request = {"AppointmentNo": appointmentNo, "NFC_Code": nfcCode, "ProjectID": projectId, "ClinicID": clinicID, "CheckinBy": checkInBy}; dynamic localRes; await baseAppClient.post(SEND_CHECK_IN_NFC_REQUEST, onSuccess: (response, statusCode) async { localRes = response; @@ -1548,6 +1650,19 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future checkScannedNFCAndQRCode(String nfcCode, int projectId) async { + Map request; + + request = {"NFC_Code": nfcCode, "ProjectID": projectId}; + dynamic localRes; + await baseAppClient.post(CHECK_SCANNED_NFC_QR_CODE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future checkIfHasDentalPlan(int projectID, BuildContext context) async { Map request; @@ -1765,38 +1880,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future autoGenerateInvoiceERClinicWithNoPaymentDetails(int projectID, bool isAdvanceAvailable) async { - Map request; - request = { - "ProjectID": projectID, - "ClinicID": "10", - // "PaymentMethod": cardType, - // "PaymentReferenceNo": paymentReferenceNo, - // "PaymentAmount": amount, - // "CardType": cardType, - // "CardNumber": cardNumber, - // "OrderId": orderID, - "MemberID": 102, - // "RRN": rrn, - "IsAdvanceAvailable": isAdvanceAvailable - }; - dynamic localRes; - await baseAppClient.post(AUTO_GENERATE_INVOICE_ER, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request, isAllowAny: true); - - return Future.value(localRes); - } - - Future autoGenerateInvoiceERClinic( - int projectID, int paymentMethod, String paymentReferenceNo, num amount, String cardType, String cardNumber, String orderID, String rrn, bool isAdvanceAvailable) async { + Future autoGenerateInvoiceERClinic(int? projectID, int? paymentMethod, String? paymentReferenceNo, num? amount, String? cardType, String? cardNumber, String? orderID, String? rrn, bool isAdvanceAvailable) async { Map request; request = { "ProjectID": projectID, "ClinicID": "10", - "PaymentMethod": cardType, + // "PaymentMethod": paymentMethod, + "PaymentMethod": "VISA", "PaymentReferenceNo": paymentReferenceNo, "PaymentAmount": amount, "CardType": cardType, diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index 1a61ecca..81a3dfad 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -339,12 +339,12 @@ class AuthProvider with ChangeNotifier { return authenticatedUser; } - Future checkPatientForRegisteration(CheckPatientForRegistration request) async { + Future checkPatientForRegisteration(CheckPatientForRegistration request, int languageID) async { request.versionID = VERSION_ID; request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.languageID = (languageID == 'ar' ? 1 : 2); + request.languageID = languageID; request.deviceTypeID = Platform.isIOS ? 1 : 2; request.isRegister = false; // request.tokenID = ''; @@ -410,6 +410,1282 @@ class AuthProvider with ChangeNotifier { dynamic localRes; try { + // localRes = { + // "Date": null, + // "LanguageID": 0, + // "ServiceName": 0, + // "Time": null, + // "AndroidLink": null, + // "AuthenticationTokenID": "d+TXwG6BFkSjRuFPvTdSwA==", + // "Data": null, + // "Dataw": false, + // "DietType": 0, + // "DietTypeID": 0, + // "ErrorCode": null, + // "ErrorEndUserMessage": "Patient verified Successfully", + // "ErrorEndUserMessageN": null, + // "ErrorMessage": null, + // "ErrorStatusCode": 0, + // "ErrorType": 0, + // "FoodCategory": 0, + // "IOSLink": null, + // "IsAuthenticated": true, + // "MealOrderStatus": 0, + // "MealType": 0, + // "MessageStatus": 1, + // "NumberOfResultRecords": 0, + // "PatientBlodType": null, + // "SuccessMsg": null, + // "SuccessMsgN": null, + // "VidaUpdatedResponse": null, + // "DoctorInformation_List": null, + // "GetAllPendingRecordsList": null, + // "GetAllSharedRecordsByStatusList": null, + // "GetResponseFileList": null, + // "IsHMGPatient": false, + // "IsLoginSuccessfully": false, + // "IsNeedUpdateIdintificationNo": false, + // "IsPatientAuthorized": false, + // "IsVidaPlus": false, + // "KioskSendSMS": false, + // "List": [ + // { + // "SetupID": "010266", + // "PatientType": 1, + // "PatientID": 5318335, + // "FirstName": "SYED TAHA", + // "MiddleName": "ALAM", + // "LastName": "ALAM", + // "FirstNameN": "سيد طه", + // "MiddleNameN": "علام", + // "LastNameN": "علام", + // "RelationshipID": 0, + // "Gender": 1, + // "DateofBirth": "/Date(839106000000+0300)/", + // "DateofBirthN": null, + // "NationalityID": "PAK", + // "PhoneResi": " ", + // "PhoneOffice": " ", + // "MobileNumber": "0560960398", + // "FaxNumber": " ", + // "EmailAddress": "testtaha@gmail.com", + // "BloodGroup": null, + // "RHFactor": null, + // "IsEmailAlertRequired": false, + // "IsSMSAlertRequired": true, + // "PreferredLanguage": "1", + // "IsPrivilegedMember": false, + // "MemberID": null, + // "ExpiryDate": null, + // "IsHmgEmployee": null, + // "EmployeeID": null, + // "EmergencyContactName": "", + // "EmergencyContactNo": "", + // "PatientPayType": 0, + // "DHCCPatientRefID": null, + // "IsPatientDummy": false, + // "Status": 2, + // "IsStatusCleared": null, + // "PatientIdentificationType": 2, + // "PatientIdentificationNo": "2579628724", + // "ProjectID": 15, + // "InfoSourceID": 0, + // "Address": "", + // "Age": 28, + // "AgeDesc": "28 Yr", + // "AreaID": 0, + // "CRSVerificationStatus": 2, + // "CRSVerificationStatusDesc": "verified", + // "CRSVerificationStatusDescN": "تم التوثيق", + // "CreatedBy": 0, + // "GenderDescription": "Male", + // "HealthIDFromNHICViaVida": "2bcc1b1a-96b7-4f33-86e2-fa955d0e3764", + // "IR": null, + // "ISOCityID": null, + // "ISOCountryID": null, + // "IsVerfiedFromNHIC": true, + // "ListPrivilege": [ + // { + // "ID": 1, + // "ServiceName": "Notifications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 2, + // "ServiceName": "Family Files", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 3, + // "ServiceName": "Settings", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 4, + // "ServiceName": "My Profile", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 5, + // "ServiceName": "My Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 6, + // "ServiceName": "My Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 7, + // "ServiceName": "Radiology", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 8, + // "ServiceName": "Radiology Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 9, + // "ServiceName": "Radiology View Image", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 10, + // "ServiceName": "Lab Results", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 11, + // "ServiceName": "Lab Results Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 12, + // "ServiceName": "Precriptions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 13, + // "ServiceName": "Precriptions Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 14, + // "ServiceName": "Eye Measurments", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 15, + // "ServiceName": "Eye Measurments Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 16, + // "ServiceName": "Sick Leaves", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 17, + // "ServiceName": "Sick Leaves Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 18, + // "ServiceName": "Approvals", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 19, + // "ServiceName": "Monthly Reports", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 20, + // "ServiceName": "Request Medical Report", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 21, + // "ServiceName": "Request Medical Report Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 22, + // "ServiceName": "Insurance Cards", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 23, + // "ServiceName": "Allergies", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 24, + // "ServiceName": "My Trackers", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 25, + // "ServiceName": "Vital Signs", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 26, + // "ServiceName": "My Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 27, + // "ServiceName": "My Vaccines Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 28, + // "ServiceName": "Ask Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 29, + // "ServiceName": "Live Chat", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 30, + // "ServiceName": "Health Data", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 31, + // "ServiceName": "Online Check-in", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 32, + // "ServiceName": "Connect to internet", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 33, + // "ServiceName": "Advance Payment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 34, + // "ServiceName": "Book Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 35, + // "ServiceName": "Child Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 36, + // "ServiceName": "Blood Donation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 38, + // "ServiceName": "H2O", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 40, + // "ServiceName": "ChatBot", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 41, + // "ServiceName": "Parking", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 42, + // "ServiceName": "SymptomChecker", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 47, + // "ServiceName": "AdvanceBalance", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 48, + // "ServiceName": "ActiveMedications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 49, + // "ServiceName": "VaccineAvailability", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 51, + // "ServiceName": "UpcomingAppointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 52, + // "ServiceName": "PushNotificationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 53, + // "ServiceName": "ActiveMedicationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 54, + // "ServiceName": "LabOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 55, + // "ServiceName": "RadOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 56, + // "ServiceName": "MedicalReportUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 57, + // "ServiceName": "ERWaittingTimeShowing", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 58, + // "ServiceName": "OnlinePayment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 59, + // "ServiceName": "RadiologyDisplayImage", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 60, + // "ServiceName": "EmergencyConsultation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 61, + // "ServiceName": "PatientQueueCall", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 62, + // "ServiceName": "OnlinePrescriptionOrder", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 63, + // "ServiceName": "Transportations", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 64, + // "ServiceName": "HomeHealthCareService", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 65, + // "ServiceName": "Al-HabibPharmacyOnline", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 66, + // "ServiceName": "Al-HabibOffers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 67, + // "ServiceName": "ComprehensiveMedicalCheckup", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 68, + // "ServiceName": "RRT", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 72, + // "ServiceName": "CancelLiveCareRequest", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 74, + // "ServiceName": "Exacart", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 76, + // "ServiceName": "Covid19-CarThrow", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 77, + // "ServiceName": "VoiceBot", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 78, + // "ServiceName": "LiveCareBookOnDoctorSchedule", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 79, + // "ServiceName": "CheckIn_QR", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 80, + // "ServiceName": "CheckIn_NFC", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 81, + // "ServiceName": "ED", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 82, + // "ServiceName": "Packages_&_Offers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 83, + // "ServiceName": "Lakum_Points", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 84, + // "ServiceName": "QR_Reader", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 85, + // "ServiceName": "AncillaryOrders", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 86, + // "ServiceName": "Payment-MADA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 87, + // "ServiceName": "Payment-VISA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 88, + // "ServiceName": "Payment-MasterCard", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 89, + // "ServiceName": "Payment-ApplePay", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 90, + // "ServiceName": "Payment-Tamara", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 91, + // "ServiceName": "Payment-Installment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 92, + // "ServiceName": "ED-Checkin", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 93, + // "ServiceName": "NetworkDebug", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 94, + // "ServiceName": "TamaraAncillary", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 95, + // "ServiceName": "Verif-Face", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 96, + // "ServiceName": "Verif-Finger", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 97, + // "ServiceName": "Verif-SMS", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 98, + // "ServiceName": "Verif-WhatsApp", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 99, + // "ServiceName": "PharmacyLivecare", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 100, + // "ServiceName": "ePharmacy", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 102, + // "ServiceName": "CheckIn_Geofence", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 103, + // "ServiceName": "Payment-ApplePay-Web", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 104, + // "ServiceName": "Livecare_Zoom", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 105, + // "ServiceName": "Dental Virtual Tour", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 106, + // "ServiceName": "Dental Medical Instructions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 107, + // "ServiceName": "Navigation Service", + // "Previlege": false, + // "Region": null + // } + // ], + // "Marital": null, + // "OutSA": 0, + // "POBox": "", + // "ReceiveHealthSummaryReport": false, + // "SourceType": 0, + // "StrDateofBirth": null, + // "TempAddress": "", + // "ZipCode": "", + // "eHealthIDField": null, + // "patientPayType": null, + // "patientType": null, + // "status": null + // } + // ], + // "List_AskHabibMobileLoginInfo": null, + // "List_AskHabibPatientFile": null, + // "List_FamilyRelationships": null, + // "List_MergeFiles": null, + // "List_MobileLoginInfo": null, + // "List_PatientCount": null, + // "LogInTokenID": null, + // "MohemmPrivilege_List": null, + // "PateintID": 5318335, + // "PatientBloodType": "", + // "PatientER_AdminDriverFileList": null, + // "PatientER_AdminFile": null, + // "PatientER_DriverFile": null, + // "PatientER_DriverFileList": null, + // "PatientHasFile": false, + // "PatientMergedIDs": null, + // "PatientOutSA": false, + // "PatientShareRequestID": 0, + // "PatientType": 0, + // "ProjectIDOut": 0, + // "ReturnMessage": null, + // "SMSLoginRequired": false, + // "ServicePrivilege_List": [ + // { + // "ID": 1, + // "ServiceName": "Notifications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 2, + // "ServiceName": "Family Files", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 3, + // "ServiceName": "Settings", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 4, + // "ServiceName": "My Profile", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 5, + // "ServiceName": "My Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 6, + // "ServiceName": "My Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 7, + // "ServiceName": "Radiology", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 8, + // "ServiceName": "Radiology Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 9, + // "ServiceName": "Radiology View Image", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 10, + // "ServiceName": "Lab Results", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 11, + // "ServiceName": "Lab Results Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 12, + // "ServiceName": "Precriptions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 13, + // "ServiceName": "Precriptions Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 14, + // "ServiceName": "Eye Measurments", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 15, + // "ServiceName": "Eye Measurments Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 16, + // "ServiceName": "Sick Leaves", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 17, + // "ServiceName": "Sick Leaves Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 18, + // "ServiceName": "Approvals", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 19, + // "ServiceName": "Monthly Reports", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 20, + // "ServiceName": "Request Medical Report", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 21, + // "ServiceName": "Request Medical Report Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 22, + // "ServiceName": "Insurance Cards", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 23, + // "ServiceName": "Allergies", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 24, + // "ServiceName": "My Trackers", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 25, + // "ServiceName": "Vital Signs", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 26, + // "ServiceName": "My Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 27, + // "ServiceName": "My Vaccines Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 28, + // "ServiceName": "Ask Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 29, + // "ServiceName": "Live Chat", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 30, + // "ServiceName": "Health Data", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 31, + // "ServiceName": "Online Check-in", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 32, + // "ServiceName": "Connect to internet", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 33, + // "ServiceName": "Advance Payment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 34, + // "ServiceName": "Book Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 35, + // "ServiceName": "Child Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 36, + // "ServiceName": "Blood Donation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 38, + // "ServiceName": "H2O", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 40, + // "ServiceName": "ChatBot", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 41, + // "ServiceName": "Parking", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 42, + // "ServiceName": "SymptomChecker", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 47, + // "ServiceName": "AdvanceBalance", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 48, + // "ServiceName": "ActiveMedications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 49, + // "ServiceName": "VaccineAvailability", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 51, + // "ServiceName": "UpcomingAppointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 52, + // "ServiceName": "PushNotificationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 53, + // "ServiceName": "ActiveMedicationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 54, + // "ServiceName": "LabOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 55, + // "ServiceName": "RadOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 56, + // "ServiceName": "MedicalReportUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 57, + // "ServiceName": "ERWaittingTimeShowing", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 58, + // "ServiceName": "OnlinePayment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 59, + // "ServiceName": "RadiologyDisplayImage", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 60, + // "ServiceName": "EmergencyConsultation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 61, + // "ServiceName": "PatientQueueCall", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 62, + // "ServiceName": "OnlinePrescriptionOrder", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 63, + // "ServiceName": "Transportations", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 64, + // "ServiceName": "HomeHealthCareService", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 65, + // "ServiceName": "Al-HabibPharmacyOnline", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 66, + // "ServiceName": "Al-HabibOffers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 67, + // "ServiceName": "ComprehensiveMedicalCheckup", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 68, + // "ServiceName": "RRT", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 72, + // "ServiceName": "CancelLiveCareRequest", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 74, + // "ServiceName": "Exacart", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 76, + // "ServiceName": "Covid19-CarThrow", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 77, + // "ServiceName": "VoiceBot", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 78, + // "ServiceName": "LiveCareBookOnDoctorSchedule", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 79, + // "ServiceName": "CheckIn_QR", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 80, + // "ServiceName": "CheckIn_NFC", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 81, + // "ServiceName": "ED", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 82, + // "ServiceName": "Packages_&_Offers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 83, + // "ServiceName": "Lakum_Points", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 84, + // "ServiceName": "QR_Reader", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 85, + // "ServiceName": "AncillaryOrders", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 86, + // "ServiceName": "Payment-MADA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 87, + // "ServiceName": "Payment-VISA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 88, + // "ServiceName": "Payment-MasterCard", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 89, + // "ServiceName": "Payment-ApplePay", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 90, + // "ServiceName": "Payment-Tamara", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 91, + // "ServiceName": "Payment-Installment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 92, + // "ServiceName": "ED-Checkin", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 93, + // "ServiceName": "NetworkDebug", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 94, + // "ServiceName": "TamaraAncillary", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 95, + // "ServiceName": "Verif-Face", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 96, + // "ServiceName": "Verif-Finger", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 97, + // "ServiceName": "Verif-SMS", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 98, + // "ServiceName": "Verif-WhatsApp", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 99, + // "ServiceName": "PharmacyLivecare", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 100, + // "ServiceName": "ePharmacy", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 102, + // "ServiceName": "CheckIn_Geofence", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 103, + // "ServiceName": "Payment-ApplePay-Web", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 104, + // "ServiceName": "Livecare_Zoom", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 105, + // "ServiceName": "Dental Virtual Tour", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 106, + // "ServiceName": "Dental Medical Instructions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 107, + // "ServiceName": "Navigation Service", + // "Previlege": false, + // "Region": null + // } + // ], + // "SharePatientName": null, + // "UserAccountIsActivated": false, + // "VerificationCode": null, + // "email": null, + // "errorList": null, + // "hasFile": false, + // "isActiveCode": false, + // "isMerged": false, + // "isNeedUserAgreement": false, + // "isSMSSent": false, + // "memberList": null, + // "message": "Patient Registered Successfully", + // "statusCode": 1 + // }; await new BaseAppClient().post(REGISTER_USER, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { @@ -458,7 +1734,7 @@ class AuthProvider with ChangeNotifier { Request req = appGlobal.getPublicRequest(); request = { - "PatientOutSA": zipCode == '+966' ? 0 : 1, + "PatientOutSA": zipCode == '966' ? 0 : 1, "PatientMobileNumber": mobileNo, "SearchType": 2, "ZipCode": zipCode, @@ -499,6 +1775,60 @@ class AuthProvider with ChangeNotifier { } } + Future checkIfUserAgreed() async { + Map request; + request = {"Region": 1}; + dynamic localRes; + try { + await new BaseAppClient().post(CHECK_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future getUserAgreementContent() async { + Map request; + request = {"Region": 1}; + dynamic localRes; + try { + await new BaseAppClient().post(GET_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future addUserAgreementContent() async { + Map request; + request = {"Region": 1}; + dynamic localRes; + try { + await new BaseAppClient().post(ADD_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + Future getDashboard() async { Map request = {}; diff --git a/lib/services/clinic_services/get_clinic_service.dart b/lib/services/clinic_services/get_clinic_service.dart index d8aa4ca9..af2828cc 100644 --- a/lib/services/clinic_services/get_clinic_service.dart +++ b/lib/services/clinic_services/get_clinic_service.dart @@ -34,6 +34,19 @@ class ClinicListService extends BaseService { return Future.value(localRes); } + Future getClinicByHospital({required String projectID}) async { + Map request = {"ProjectID": projectID}; + + dynamic localRes; + + await baseAppClient.post(GET_CLINICS_LIST_WRT_HOSPITAL_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getActiveAppointmentNo(context) async { Map request = {}; @@ -52,7 +65,7 @@ class ClinicListService extends BaseService { Future getProjectsList(int languageID, context) async { Map request = {}; - request = {"LanguageID": languageID}; + // request = {"LanguageID": languageID}; dynamic localRes; @@ -156,6 +169,7 @@ class ClinicListService extends BaseService { }, body: request); return Future.value(localRes); } + Future getInPatientAdvancePaymentHistory(int projectID, int admissionNo, int admissionReqNo, context) async { Map request; request = {"ProjectID": projectID, "AdmissionNo": admissionNo, "AdmissionReqNo": admissionReqNo}; @@ -200,6 +214,7 @@ class ClinicListService extends BaseService { }, body: request, isAllowAny: true); return Future.value(localRes); } + Future submitBirthNotification(num motherMRN, int projectID, String fatherNameAR, String fatherNameEN, String babyNameAR, String babyNameEN, String contactNum, String idImage, context) async { Map request; request = { @@ -223,8 +238,8 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future insertInPatientOrder(GetAdmissionInfoResponseModel getAdmissionInfoResponseModel, int typeID, String patientName, String patientNameAR, String patientMobileNo, String comments, - context) async { + Future insertInPatientOrder( + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel, int typeID, String patientName, String patientNameAR, String patientMobileNo, String comments, context) async { Map request; request = { "ProjectID": getAdmissionInfoResponseModel.projectID, @@ -249,9 +264,9 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getGeneralInstructions(int projectID, context) async { + Future getGeneralInstructions(int projectID, int languageID, context) async { Map request; - request = {"ProjectID": projectID}; + request = {"ProjectID": projectID, "LanguageID": languageID}; dynamic localRes; @@ -262,9 +277,10 @@ class ClinicListService extends BaseService { }, body: request, isAllowAny: true); return Future.value(localRes); } - Future getMedicalInstructions(int projectID, context) async { + + Future getMedicalInstructions(int projectID, int languageID, context) async { Map request; - request = {"ProjectID": projectID}; + request = {"ProjectID": projectID, "LanguageID": languageID}; dynamic localRes; @@ -276,9 +292,9 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getInPatientAdvancePaymentRequests(int projectID, int admissionNo, int admissionReqNo, context) async { + Future getInPatientAdvancePaymentRequests(int projectID, int admissionNo, int admissionReqNo, int languageID, context) async { Map request; - request = {"ProjectID": projectID, "AdmissionReqNo": admissionReqNo, "AdmissionNo": admissionNo}; + request = {"ProjectID": projectID, "AdmissionReqNo": admissionReqNo, "AdmissionNo": admissionNo, "LanguageID": languageID}; dynamic localRes; @@ -290,11 +306,9 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getBirthNotification(num motherMRN, context) async { + Future getBirthNotification(num motherMRN, int projectID, int languageID, context) async { Map request; - request = { - "mothermrn": motherMRN, - }; + request = {"mothermrn": motherMRN, "LanguageID": languageID, "ProjectID": projectID}; dynamic localRes; @@ -319,6 +333,7 @@ class ClinicListService extends BaseService { }, body: request, isAllowAny: true); return Future.value(localRes); } + Future getCurrentWeekIDAndDay(BuildContext context) async { dynamic localRes; await baseAppClient.get(GET_CURRENT_WEEKID_WEEKDAY, isExternal: false, isRCService: false, onSuccess: (response, statusCode) async { @@ -400,6 +415,7 @@ class ClinicListService extends BaseService { }, body: request, isAllowAny: true); return Future.value(localRes); } + Future checkIfInPatientAPI(context) async { Map request; request = { @@ -416,7 +432,6 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getWeCareURL(int projectID) async { Map request = {"ProjectID": projectID}; dynamic localRes; @@ -461,10 +476,10 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future checkPatientERClinicBalanceAmount(int clinicID) async { + Future checkPatientERAdvanceBalance(int clinicID) async { Map request = {"ClinicID": clinicID}; dynamic localRes; - await baseAppClient.post(CHECK_PATIENT_ER_CLINIC_BALANCE_AMOUNT, onSuccess: (response, statusCode) async { + await baseAppClient.post(CHECK_PATIENT_ER_ADVANCE_BALANCE, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -482,4 +497,66 @@ class ClinicListService extends BaseService { }, body: request, isAllowAny: true); return Future.value(localRes); } + + Future getDischargeMedicationOrder(GetAdmissionInfoResponseModel getAdmissionInfoResponseModel) async { + Map request; + request = { + "ProjectID": getAdmissionInfoResponseModel.projectID, + "ClinicID": getAdmissionInfoResponseModel.clinicID, + "DoctorID": getAdmissionInfoResponseModel.doctorID, + "AdmissionNo": getAdmissionInfoResponseModel.admissionNo + }; + + // request = { + // "ProjectID": 12, + // "VersionID": 10.8, + // "Channel": 3, + // "LanguageID": 2, + // "IPAdress": "10.20.10.20", + // "generalid": "Cs2020@2016\$2958", + // "DeviceTypeID": 2, + // "PatientType": 1, + // "PatientTypeID": 1, + // "TokenID": "@dm!n", + // "PatientID": 869588, + // "PatientOutSA": 0, + // "SessionID": "rVuK3nzN4UKN0SW95un0jQ==", + // "ClinicID": 2, + // "DoctorID": "7600", + // "AdmissionNo": 2011001258 + // }; + + dynamic localRes; + + await baseAppClient.post(INPATIENT_DISCHARGE_MEDICATIONS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future insertForGeneralAdmissionConsent(int patientID, int admissionReqNo, int clinicID, int projectID, int status, context) async { + Map request; + request = { + "AdmissionRequestNo": admissionReqNo, + "ClinicID": clinicID, + "CreatedBy": 102, + "PatientID": patientID, + "ProjectID": projectID, + "status": status, + "searchKey": "", + "pageIndex": 0, + "pageSize": 0, + }; + + dynamic localRes; + + await baseAppClient.post(INSERT_GENERAL_ADMISSION_CONSENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } } diff --git a/lib/services/payfort_services/payfort_service.dart b/lib/services/payfort_services/payfort_service.dart index a1bbccd8..5dedd006 100644 --- a/lib/services/payfort_services/payfort_service.dart +++ b/lib/services/payfort_services/payfort_service.dart @@ -54,7 +54,7 @@ class PayfortService extends BaseService { "Pat_Token": result.tokenName, "IsRefund": false, "RemmeberMe": false, - "Reconciliation_Reference": result.reconciliationReference, + // "Reconciliation_Reference": result.reconciliationReference, "LanguageID": 1, "PatientID": patientID }; @@ -161,22 +161,23 @@ class PayfortService extends BaseService { ); if (sdkTokenResponse != null && sdkTokenResponse.sdkToken == null) { - onFailed!(sdkTokenResponse.responseMessage ?? ''); + onFailed!((sdkTokenResponse.responseMessage ?? '') as PayFortFailureResult); return; } /// Step 4: Processing Payment [Don't multiply with 100] /// Amount value send always round ex. [100] not [100.00, 100.21] FortRequest request = FortRequest( - amount: orderAmount!, - customerName: customerName!, - customerEmail: customerEmail!, - orderDescription: orderDescription!, - sdkToken: sdkTokenResponse?.sdkToken ?? '', - merchantReference: merchantReference!, - currency: currency, - customerIp: (await _info.getWifiIP() ?? ''), - ); + amount: orderAmount!, + customerName: customerName!, + customerEmail: customerEmail!, + // orderDescription: orderDescription!, + orderDescription: "Dr. Sulaiman Al Habib Hospital", + sdkToken: sdkTokenResponse?.sdkToken ?? '', + merchantReference: merchantReference!, + currency: currency, + customerIp: (await _info.getWifiIP() ?? ''), + language: 'en'); _payfort.callPayFortForApplePay( request: request, @@ -188,7 +189,7 @@ class PayfortService extends BaseService { ), ); } catch (e) { - onFailed!(e.toString()); + onFailed!(e.toString() as PayFortFailureResult); } } } diff --git a/lib/services/permission/permission_service.dart b/lib/services/permission/permission_service.dart index 641d6444..cc73c303 100644 --- a/lib/services/permission/permission_service.dart +++ b/lib/services/permission/permission_service.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:flutter/material.dart'; import 'package:localstorage/localstorage.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:vibration/vibration.dart'; +// import 'package:vibration/vibration.dart'; import 'package:geolocator/geolocator.dart' as geo; class PermissionService extends BaseService { @@ -25,10 +25,10 @@ class PermissionService extends BaseService { vibrate(callback, context) async { if (callback == null) return null; if (isVibrationEnabled() == true) { - if (await Vibration.hasVibrator() !=null) { - Vibration.vibrate(duration: 100); - callback(); - } + // if (await Vibration.hasVibrator() !=null) { + // Vibration.vibrate(duration: 100); + // callback(); + // } } else { callback(); } diff --git a/lib/splashPage.dart b/lib/splashPage.dart index 515c7f54..533456ee 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -11,6 +11,8 @@ import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/push-notification-handler.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; @@ -84,6 +86,7 @@ class _SplashScreenState extends State { // debugPrint("ALL SHARED PREFERENCES!!!!!"); // debugPrint(jsonEncode(value)); }); + if (!kDebugMode) await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); // PushNotificationHandler(context).init(); // Asyncronously } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 328af105..a9d4e437 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -21,6 +21,7 @@ class CustomColors { static const Color appBackgroudGrey2Color = Color(0xFFF8F8F8); static const Color green = Color(0xFF359846); static const Color orange = Color(0xFFCC9B14); + static const Color darkOrange = Color(0xFFE16F17); static const Color femaleColor = Color(0xFF359846); static const Color maleColor = Color(0xFFCC9B14); diff --git a/lib/theme/theme_value.dart b/lib/theme/theme_value.dart index 5cf871ab..4fd06d9c 100644 --- a/lib/theme/theme_value.dart +++ b/lib/theme/theme_value.dart @@ -27,22 +27,22 @@ defaultTheme({fontName}) { ), hintColor: Colors.grey[400], disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xffF8F8F8), canvasColor: Colors.white, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff515A5D), - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), - primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), + // primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), iconTheme: IconThemeData(), textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.black, letterSpacing: 0.6), - headline1: TextStyle(color: Colors.white, letterSpacing: 0.6), - headline2: TextStyle(color: Colors.white, letterSpacing: 0.6), + // bodyText1: TextStyle(color: Colors.black, letterSpacing: 0.6), + // headline1: TextStyle(color: Colors.white, letterSpacing: 0.6), + // headline2: TextStyle(color: Colors.white, letterSpacing: 0.6), ), floatingActionButtonTheme: FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), @@ -71,16 +71,16 @@ invertThemes({fontName}) { }, ), hintColor: Colors.grey[400], - textTheme: TextTheme(bodyText1: TextStyle(color: Colors.white), headline1: TextStyle(color: Colors.white), headline2: TextStyle(color: Colors.white)), + // textTheme: TextTheme(bodyText1: TextStyle(color: Colors.white), headline1: TextStyle(color: Colors.white), headline2: TextStyle(color: Colors.white)), disabledColor: Colors.grey[800], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xff000000), canvasColor: Colors.black, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff515A5D), - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), iconTheme: IconThemeData(), @@ -113,24 +113,24 @@ bwThemes({fontName}) { hintColor: Colors.grey[400], textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.red[900]), - headline1: TextStyle(color: Colors.red[900]), - headline2: TextStyle(color: Colors.white), - bodyText2: TextStyle(color: Colors.red[900]), - subtitle1: TextStyle(color: Colors.red[900]), + // bodyText1: TextStyle(color: Colors.red[900]), + // headline1: TextStyle(color: Colors.red[900]), + // headline2: TextStyle(color: Colors.white), + // bodyText2: TextStyle(color: Colors.red[900]), + // subtitle1: TextStyle(color: Colors.red[900]), ), tabBarTheme: TabBarTheme(labelColor: Colors.red[900]), disabledColor: Colors.grey[800], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xffffffe4), canvasColor: Colors.black, - backgroundColor: Color(0xffffffe4), + // backgroundColor: Color(0xffffffe4), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xfffffff4), - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), iconTheme: IconThemeData(), @@ -160,10 +160,10 @@ dimTheme({fontName}) { ), hintColor: Colors.grey[400], disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xffEEEEEE), canvasColor: Colors.white, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff40ACC9), diff --git a/lib/uitl/CalendarUtils.dart b/lib/uitl/CalendarUtils.dart index 57ec961a..59f33f10 100644 --- a/lib/uitl/CalendarUtils.dart +++ b/lib/uitl/CalendarUtils.dart @@ -5,6 +5,7 @@ import 'dart:ui'; import 'package:device_calendar/device_calendar.dart'; import 'package:manage_calendar_events/manage_calendar_events.dart' as ios; +import 'package:timezone/data/latest.dart' as tzl; final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin(); final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); @@ -44,6 +45,7 @@ class CalendarUtils { // } static Future getInstance() async { + tzl.initializeTimeZones(); if (_completer != null) { return _completer!.future; } @@ -108,10 +110,10 @@ class CalendarUtils { TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation); - // print("writableCalendars-name: " + writableCalendars.name); - // print("writableCalendars-Id: " + writableCalendars.id); - // print("writableCalendarsToString: " + writableCalendars.toString()); - // print("writableCalendarsToString: " + writableCalendars!.id!); + print("writableCalendars-name: " + writableCalendars.name); + print("writableCalendars-Id: " + writableCalendars.id); + print("writableCalendarsToString: " + writableCalendars.toString()); + print("writableCalendarsToString: " + writableCalendars!.id!); Event event = Event( writableCalendars!.id, start: scheduleDateTimeUTZ, @@ -119,11 +121,27 @@ class CalendarUtils { title: title, description: description, ); - await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) { - print("catchError " + e.toString()); - }).whenComplete(() { - print("whenComplete " + eventId!); - }); + + ios.CalendarEvent iosCalEvent = + ios.CalendarEvent(eventId: eventId, startDate: scheduleDateTimeUTZ, endDate: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description, isAllDay: false); + + if (Platform.isAndroid) { + Result result = await deviceCalendarPlugin.hasPermissions(); + print(result); + await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) { + print("catchError " + e.toString()); + }).whenComplete(() { + print("whenComplete Calender ID " + eventId!); + }); + } else { + // Result result = await deviceCalendarPlugin.hasPermissions(); + // print(result); + await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) { + print("catchError " + e.toString()); + }).whenComplete(() { + print("whenComplete Calender ID iOS " + eventId!); + }); + } } deleteEvent(Calendar _calendar, Event _event) async { diff --git a/lib/uitl/app-permissions.dart b/lib/uitl/app-permissions.dart index 62fd484a..94697e4f 100644 --- a/lib/uitl/app-permissions.dart +++ b/lib/uitl/app-permissions.dart @@ -7,9 +7,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'PlatformBridge.dart'; -class AppPermission{ - - +class AppPermission { static Future askVideoCallPermission(BuildContext context) async { if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { return false; @@ -21,6 +19,30 @@ class AppPermission{ return true; } +// + + // Manifest.permission.INTERNET, + // Manifest.permission.ACCESS_FINE_LOCATION, + // Manifest.permission.ACCESS_COARSE_LOCATION, + // Manifest.permission.ACCESS_NETWORK_STATE, + // Manifest.permission.BLUETOOTH, + // Manifest.permission.BLUETOOTH_ADMIN, + // Manifest.permission.BLUETOOTH_SCAN, + // Manifest.permission.BLUETOOTH_CONNECT, + // Manifest.permission.HIGH_SAMPLING_RATE_SENSORS, + // Manifest.permission.ACTIVITY_RECOGNITION + + static Future askPenguinPermissions() async { + if (!(await Permission.location.request().isGranted) || + !(await Permission.bluetooth.request().isGranted) || + !(await Permission.bluetoothScan.request().isGranted) || + !(await Permission.bluetoothConnect.request().isGranted) || + !(await Permission.activityRecognition.request().isGranted)) { + return false; + } + return true; + } + static Future _drawOverAppsMessageDialog(BuildContext context) async { ConfirmDialog dialog = new ConfirmDialog( context: context, @@ -34,4 +56,4 @@ class AppPermission{ cancelFunction: () => {}); dialog.showAlertDialog(context); } -} \ No newline at end of file +} diff --git a/lib/uitl/app_shared_preferences.dart b/lib/uitl/app_shared_preferences.dart index 2d5fa774..4ecd1b91 100644 --- a/lib/uitl/app_shared_preferences.dart +++ b/lib/uitl/app_shared_preferences.dart @@ -76,7 +76,8 @@ class AppSharedPreferences { final SharedPreferences prefs = await _prefs; await prefs.reload(); String value = prefs.getString(key).toString(); - return value == null ? defaultVal : value; + return (value == null) || (value == "null") ? defaultVal : value; + // return value == null ? defaultVal : value; } /// Get List of String [key] the key was saved diff --git a/lib/uitl/penguin_method_channel.dart b/lib/uitl/penguin_method_channel.dart new file mode 100644 index 00000000..50a642a7 --- /dev/null +++ b/lib/uitl/penguin_method_channel.dart @@ -0,0 +1,105 @@ +import 'package:flutter/services.dart'; + +class PenguinMethodChannel { + static const MethodChannel _channel = MethodChannel('launch_penguin_ui'); + + Future loadGif() async { + return await rootBundle.load("assets/images/progress-loading-red-crop-1.gif").then((data) => data.buffer.asUint8List()); + } + + Future launch(String storyboardName, String languageCode, String username, {NavigationClinicDetails? details}) async { + Uint8List image = await loadGif(); + try { + await _channel.invokeMethod('launchPenguin', { + "storyboardName": storyboardName, + "baseURL": "https://prod.hmg.nav.penguinin.com", + // "dataURL": "https://hmg.nav.penguinin.com", + // "positionURL": "https://hmg.nav.penguinin.com", + // "dataURL": "https://hmg-v33.local.penguinin.com", + // "positionURL": "https://hmg-v33.local.penguinin.com", + "dataURL": "https://prod.hmg.nav.penguinin.com", + "positionURL": "https://prod.hmg.nav.penguinin.com", + "dataServiceName": "api", + "positionServiceName": "pe", + "clientID": "HMG", + // "username": "Haroon", + "username": username, + "isSimulationModeEnabled": false, + "isShowUserName": false, + "isUpdateUserLocationSmoothly": true, + "isEnableReportIssue": true, + "languageCode": languageCode, + "clientKey": "UGVuZ3VpbklOX1Blbk5hdl9QSUY=", + "mapBoxKey": "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg", + "clinicID": details?.clinicId ?? "", + // "clinicID": "108", // 46 ,49, 133 + "patientID": details?.patientId ?? "", + "projectID": details?.projectId ?? "", + "loaderImage": image, + }); + } on PlatformException catch (e) { + print("Failed to launch PenguinIn: '${e.message}'."); + } + } + + void setMethodCallHandler(){ + _channel.setMethodCallHandler((MethodCall call) async { + try { + + print(call.method); + + switch (call.method) { + + case PenguinMethodNames.onPenNavInitializationError: + _handleInitializationError(call.arguments); // Handle onPenNavInitializationError errors. + break; + case PenguinMethodNames.onPenNavUIDismiss: + //todo handle pen dismissable + // _handlePenNavUIDismiss(); // Handle UI dismissal event. + break; + case PenguinMethodNames.onReportIssue: + // Handle the report issue event. + _handleInitializationError(call.arguments); + break; + default: + _handleUnknownMethod(call.method); // Handle unknown method calls. + } + } catch (e) { + print("Error handling method call '${call.method}': $e"); + // Optionally, log this error to an external service + } + }); + } + static void _handleUnknownMethod(String method) { + print("Unknown method: $method"); + // Optionally, handle this unknown method case, such as reporting or ignoring it + } + + + static void _handleInitializationError(Map error) { + final type = error['type'] as String?; + final description = error['description'] as String?; + print("Initialization Error: ${type ?? 'Unknown Type'}, ${description ?? 'No Description'}"); + + } + +} +// Define constants for method names +class PenguinMethodNames { + static const String showPenguinUI = 'showPenguinUI'; + static const String openSharedLocation = 'openSharedLocation'; + + // ---- Handler Method + static const String onPenNavSuccess = 'onPenNavSuccess'; // Tested Android,iOS + static const String onPenNavInitializationError = 'onPenNavInitializationError'; // Tested Android,iOS + static const String onPenNavUIDismiss = 'onPenNavUIDismiss'; //Tested Android,iOS + static const String onReportIssue = 'onReportIssue'; // Tested Android,iOS + static const String onLocationOffCampus = 'onLocationOffCampus'; // Tested iOS,Android + static const String navigateToPOI = 'navigateToPOI'; // Tested Android,iOS +} + +class NavigationClinicDetails { + String? clinicId; + String? patientId; + String? projectId; +} diff --git a/lib/uitl/push-notification-handler.dart b/lib/uitl/push-notification-handler.dart index 6372e326..2ad0203a 100644 --- a/lib/uitl/push-notification-handler.dart +++ b/lib/uitl/push-notification-handler.dart @@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart' as fir; @@ -356,6 +357,8 @@ class PushNotificationHandler { FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) { print("Push Notification getToken: " + token!); onToken(token!); + }).catchError((err) { + print(err); }); FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { @@ -386,9 +389,16 @@ class PushNotificationHandler { if (remoteMessage.data.isEmpty) { return; } + debugPrint('the value of the remote message is ${remoteMessage.data}'); if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) { _incomingCall(remoteMessage.data); // showCallkitIncoming(remoteMessage.data); + }if(remoteMessage.data['is_navigation'] == 'true' || remoteMessage.data['is_navigation'] == true ){ + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = remoteMessage.data['clinic_Id']; + data.patientId = remoteMessage.data['patient_Id']; + data.projectId = remoteMessage.data['project_Id']; + initPenguinSDK(data); } else { GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); @@ -406,8 +416,23 @@ class PushNotificationHandler { } } + initPenguinSDK(NavigationClinicDetails data) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", "en", "1231755", details: data); + }); + } + } + onToken(String token) async { - print("Push Notification Token: " + token); + // print("Push Notification Token: " + token); await AppSharedPreferences().setString(PUSH_TOKEN, token); DEVICE_TOKEN = token; } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 46f4807c..0f30731b 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -59,7 +59,10 @@ class TranslationBase { String get clinicName => localizedValues['clinicName'][locale.languageCode]; + String get hospitalName => localizedValues['hospitalName'][locale.languageCode]; + String get doctorName => localizedValues['doctorName'][locale.languageCode]; + String get NoClinicFound => localizedValues['NoClinicFound'][locale.languageCode]; String get nearestAppo => localizedValues['nearestAppo'][locale.languageCode]; @@ -2945,6 +2948,34 @@ class TranslationBase { String get receive => localizedValues["receive"][locale.languageCode]; String get PRO => localizedValues["PRO"][locale.languageCode]; String get patientRelationOffice => localizedValues["patientRelationOffice"][locale.languageCode]; + String get roomNo => localizedValues["roomNo"][locale.languageCode]; + String get generalConsent => localizedValues["generalConsent"][locale.languageCode]; + String get generalConsent1 => localizedValues["generalConsent1"][locale.languageCode]; + String get hospitalRules => localizedValues["hospitalRules"][locale.languageCode]; + String get generalConsent2 => localizedValues["generalConsent2"][locale.languageCode]; + String get communicationConsent => localizedValues["communicationConsent"][locale.languageCode]; + String get generalConsent3 => localizedValues["generalConsent3"][locale.languageCode]; + String get releaseConsent => localizedValues["releaseConsent"][locale.languageCode]; + String get generalConsent4 => localizedValues["generalConsent4"][locale.languageCode]; + String get generalConsent5 => localizedValues["generalConsent5"][locale.languageCode]; + String get valuables => localizedValues["valuables"][locale.languageCode]; + String get generalConsent6 => localizedValues["generalConsent6"][locale.languageCode]; + String get financialConsent => localizedValues["financialConsent"][locale.languageCode]; + String get generalConsent7 => localizedValues["generalConsent7"][locale.languageCode]; + String get dataSharingConsent => localizedValues["dataSharingConsent"][locale.languageCode]; + String get generalConsent8 => localizedValues["generalConsent8"][locale.languageCode]; + String get permissionLeaveConsent => localizedValues["permissionLeaveConsent"][locale.languageCode]; + String get generalConsent9 => localizedValues["generalConsent9"][locale.languageCode]; + String get observeConsent => localizedValues["observeConsent"][locale.languageCode]; + String get generalConsent10 => localizedValues["generalConsent10"][locale.languageCode]; + String get noGuaranteeConsent => localizedValues["noGuaranteeConsent"][locale.languageCode]; + String get generalConsent11 => localizedValues["generalConsent11"][locale.languageCode]; + String get disputeConsent => localizedValues["disputeConsent"][locale.languageCode]; + String get generalConsent12 => localizedValues["generalConsent12"][locale.languageCode]; + String get patientsRightsConsent => localizedValues["patientsRightsConsent"][locale.languageCode]; + String get generalConsent13 => localizedValues["generalConsent13"][locale.languageCode]; + String get acknowledgementConsent => localizedValues["acknowledgementConsent"][locale.languageCode]; + String get generalConsent14 => localizedValues["generalConsent14"][locale.languageCode]; String get invalidEligibility => localizedValues["invalidEligibility"][locale.languageCode]; String get invalidInsurance => localizedValues["invalidInsurance"][locale.languageCode]; String get continueCash => localizedValues["continueCash"][locale.languageCode]; @@ -2963,8 +2994,33 @@ class TranslationBase { String get selectHospitalBloodDonation => localizedValues["selectHospitalBloodDonation"][locale.languageCode]; String get wecare => localizedValues["wecare"][locale.languageCode]; String get myinstructions => localizedValues["myinstructions"][locale.languageCode]; - - + String get clinicLocation => localizedValues["clinicLocation"][locale.languageCode]; + String get waitingAppointment => localizedValues["waitingAppointment"][locale.languageCode]; + String get whatWaitingAppointment => localizedValues["whatWaitingAppointment"][locale.languageCode]; + String get waitingAppointmentText1 => localizedValues["waitingAppointmentText1"][locale.languageCode]; + String get waitingAppointmentText2 => localizedValues["waitingAppointmentText2"][locale.languageCode]; + String get waitingAppointmentText3 => localizedValues["waitingAppointmentText3"][locale.languageCode]; + String get waitingAppointmentVerificationMethod => localizedValues["waitingAppointmentVerificationMethod"][locale.languageCode]; + String get howToUseVerificationMethod => localizedValues["howToUseVerificationMethod"][locale.languageCode]; + String get addToWaitingList => localizedValues["addToWaitingList"][locale.languageCode]; + String get searchClinic => localizedValues["searchClinic"][locale.languageCode]; + String get selectBranch => localizedValues["selectBranch"][locale.languageCode]; + String get searchByBranch => localizedValues["searchByBranch"][locale.languageCode]; + String get existingPackage => localizedValues["existingPackage"][locale.languageCode]; + String get continueOrbookNew => localizedValues["continueOrbookNew"][locale.languageCode]; + String get newAppointment => localizedValues["newAppointment"][locale.languageCode]; + String get proceedPackage => localizedValues["proceedPackage"][locale.languageCode]; + String get hospitalNavigationTitle => localizedValues["hospitalNavigationTitle"][locale.languageCode]; + String get hospitalNavigationSubtitle => localizedValues["hospitalNavigationSubtitle"][locale.languageCode]; + String get workplaceNameAr => localizedValues["workplaceNameAr"][locale.languageCode]; + String get occupationNameEn => localizedValues["occupationNameEn"][locale.languageCode]; + String get occupationNameAr => localizedValues["occupationNameAr"][locale.languageCode]; + String get continueAgreeTerms => localizedValues["continueAgreeTerms"][locale.languageCode]; + String get agreeText => localizedValues["agreeText"][locale.languageCode]; + String get ERCheckInSuccess => localizedValues["ERCheckInSuccess"][locale.languageCode]; + String get generalConsentTitle => localizedValues["generalConsentTitle"][locale.languageCode]; + String get generalConsentSubTitle => localizedValues["generalConsentSubTitle"][locale.languageCode]; + String get incorrectNationalId => localizedValues["incorrectNationalId"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 9b59e200..1529d605 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -65,6 +65,30 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); class Utils { // static ProgressDialog pr; + static var navigationProjectsList = [ + { + "Desciption": "Sahafa Hospital", + "DesciptionN": "مستشفى الصحافة", + "ID": 130, + "LegalName": "Sahafa Hospital", + "LegalNameN": "مستشفى الصحافة", + "Name": "Sahafa Hospital", + "NameN": "مستشفى الصحافة", + "PhoneNumber": "+966115222222", + "SetupID": "013311", + "DistanceInKilometers": 0, + "HasVida3": false, + "IsActive": true, + "IsHmg": true, + "IsVidaPlus": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "MainProjectID": 130, + "ProjectOutSA": false, + "UsingInDoctorApp": false + } + ]; + ///show custom Error Toast /// [message] to show for user static showErrorToast([String? message]) { @@ -807,7 +831,8 @@ class Utils { children: [ SizedBox(height: 12), Text( - isCapitable && !projectViewModel.isArabic ? text.toLowerCase().capitalizeFirstofEach : text, + // isCapitable && !projectViewModel.isArabic ? text.toLowerCase().capitalizeFirstofEach : text, + text, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), @@ -908,7 +933,7 @@ class Utils { return projectDetailListModel; } - //static String generateSignature() {} +//static String generateSignature() {} } Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) { diff --git a/lib/widgets/LoadingButton.dart b/lib/widgets/LoadingButton.dart index 8f94cdde..6a497198 100644 --- a/lib/widgets/LoadingButton.dart +++ b/lib/widgets/LoadingButton.dart @@ -138,14 +138,15 @@ class _AnimatedButtonState extends State /// sets width and size animation void _updateWidth() { final theme = Theme.of(context); - final fontSize = theme.textTheme.button!.fontSize; + // final fontSize = theme.textTheme.button!.fontSize; + final fontSize = 12.0; final renderParagraph = RenderParagraph( TextSpan( text: widget.text, style: TextStyle( fontSize: fontSize, - fontWeight: theme.textTheme.button!.fontWeight, - letterSpacing: theme.textTheme.button!.letterSpacing, + fontWeight: FontWeight.normal, + letterSpacing: 0.6, ), ), textDirection: TextDirection.ltr, diff --git a/lib/widgets/bottom_options/BottomSheet.dart b/lib/widgets/bottom_options/BottomSheet.dart index 3a49f3d8..135a9731 100644 --- a/lib/widgets/bottom_options/BottomSheet.dart +++ b/lib/widgets/bottom_options/BottomSheet.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -122,7 +123,7 @@ class _BottomSheet extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration(color: Theme.of(context).backgroundColor, borderRadius: BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), child: SafeArea( top: false, child: Column( @@ -165,14 +166,14 @@ class _BottomSheetItem extends StatelessWidget { if (icon != null) Icon( icon, - color: color == ITEM_COLOR.error ? Theme.of(context).errorColor : Theme.of(context).primaryColor, + color: color == ITEM_COLOR.error ? CustomColors.accentColor : Theme.of(context).primaryColor, size: 18.0, ), if (icon != null) SizedBox(width: 24.0), Texts( title ?? "", style: "bodyText2", - color: color == ITEM_COLOR.error ? Theme.of(context).errorColor : null, + color: color == ITEM_COLOR.error ? CustomColors.accentColor : null, ), ], ), diff --git a/lib/widgets/buttons/BottomButton.dart b/lib/widgets/buttons/BottomButton.dart index f4aafdb4..1746ee13 100644 --- a/lib/widgets/buttons/BottomButton.dart +++ b/lib/widgets/buttons/BottomButton.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:flutter/material.dart'; @@ -23,18 +24,7 @@ class BottomButton extends StatelessWidget { final Widget? child; final bool disabledPadding; - BottomButton( - {Key? key, - this.loading = false, - this.disabled = false, - this.label, - this.icon, - this.color, - this.textColor, - this.disabledPadding = false, - this.borderColor, - this.onTap, - this.child}) + BottomButton({Key? key, this.loading = false, this.disabled = false, this.label, this.icon, this.color, this.textColor, this.disabledPadding = false, this.borderColor, this.onTap, this.child}) : super(key: key); @override @@ -44,17 +34,7 @@ class BottomButton extends StatelessWidget { children: [ Container( decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [ - 0.0, - 0.9 - ], - colors: [ - Theme.of(context).backgroundColor, - Theme.of(context).backgroundColor.withOpacity(0) - ]), + gradient: LinearGradient(begin: Alignment.bottomCenter, end: Alignment.topCenter, stops: [0.0, 0.9], colors: [CustomColors.white, CustomColors.white.withOpacity(0)]), ), alignment: Alignment.center, child: SafeArea( @@ -63,46 +43,19 @@ class BottomButton extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Container( - margin: child != null - ? EdgeInsets.only( - left: 14.0, right: 14.0, top: 14.0, bottom: 14) - : EdgeInsets.only( - left: 30.0, right: 30.0, top: 14.0, bottom: 14), + margin: child != null ? EdgeInsets.only(left: 14.0, right: 14.0, top: 14.0, bottom: 14) : EdgeInsets.only(left: 30.0, right: 30.0, top: 14.0, bottom: 14), decoration: BoxDecoration( - color: child != null - ? Theme.of(context).backgroundColor - : null, - border: child != null - ? Border.all( - color: Theme.of(context).dividerColor, width: 2.0) - : Border.all(color: Colors.transparent, width: 0.0), - borderRadius: child != null - ? BorderRadius.circular(16.0) - : BorderRadius.circular(0.0), - boxShadow: child != null - ? [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.04), - spreadRadius: -0.0, - offset: Offset(0, 4.0), - blurRadius: 18.0) - ] - : []), + color: child != null ? CustomColors.white : null, + border: child != null ? Border.all(color: Theme.of(context).dividerColor, width: 2.0) : Border.all(color: Colors.transparent, width: 0.0), + borderRadius: child != null ? BorderRadius.circular(16.0) : BorderRadius.circular(0.0), + boxShadow: child != null ? [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.04), spreadRadius: -0.0, offset: Offset(0, 4.0), blurRadius: 18.0)] : []), child: Column( children: [ if (child != null) Padding( padding: disabledPadding - ? EdgeInsets.only( - left: 0.0, - right: 0.0, - top: 14.0, - bottom: label != null ? 0.0 : 14) - : EdgeInsets.only( - left: 18.0, - right: 18.0, - top: 14.0, - bottom: label != null ? 0.0 : 14), + ? EdgeInsets.only(left: 0.0, right: 0.0, top: 14.0, bottom: label != null ? 0.0 : 14) + : EdgeInsets.only(left: 18.0, right: 18.0, top: 14.0, bottom: label != null ? 0.0 : 14), child: child, ), if (child != null) @@ -114,10 +67,7 @@ class BottomButton extends StatelessWidget { label == null ? SizedBox(height: 50.0) : Padding( - padding: child != null - ? EdgeInsets.only( - bottom: 16.0, left: 16.0, right: 16.0) - : EdgeInsets.zero, + padding: child != null ? EdgeInsets.only(bottom: 16.0, left: 16.0, right: 16.0) : EdgeInsets.zero, child: SecondaryButton( borderColor: borderColor, onTap: () { @@ -135,8 +85,7 @@ class BottomButton extends StatelessWidget { ), if (label == null && child == null) Padding( - padding: EdgeInsets.only( - left: 30.0, right: 30.0, top: 14.0, bottom: 14), + padding: EdgeInsets.only(left: 30.0, right: 30.0, top: 14.0, bottom: 14), ), ], ), diff --git a/lib/widgets/data_display/list/flexible_container.dart b/lib/widgets/data_display/list/flexible_container.dart index 8f374ca3..63053401 100644 --- a/lib/widgets/data_display/list/flexible_container.dart +++ b/lib/widgets/data_display/list/flexible_container.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/material.dart'; /// Flexible container widget /// [widthFactor] If non-null, the fraction of the incoming width given to the child. @@ -33,7 +34,7 @@ class FlexibleContainer extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.0), child: Material( - color: Theme.of(context).backgroundColor, + color: CustomColors.white, child: Container( padding: padding, width: double.infinity, diff --git a/lib/widgets/data_display/services)contaniner.dart b/lib/widgets/data_display/services)contaniner.dart index e18507f4..246fad78 100644 --- a/lib/widgets/data_display/services)contaniner.dart +++ b/lib/widgets/data_display/services)contaniner.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/material.dart'; @@ -15,7 +16,8 @@ class ServicesContainer extends StatelessWidget { height: 60, margin: EdgeInsets.all(8), decoration: BoxDecoration( - color: Theme.of(context).textTheme.headline2!.color, + // color: Theme.of(context).textTheme.headline2!.color, + color: CustomColors.white, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), ), diff --git a/lib/widgets/data_display/text.dart b/lib/widgets/data_display/text.dart index 498e5e48..8a5b5954 100644 --- a/lib/widgets/data_display/text.dart +++ b/lib/widgets/data_display/text.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -26,30 +27,31 @@ class Texts extends StatefulWidget { final TextDecoration? decoration; final double? heightFactor; - Texts(this.text, - {Key? key, - this.variant, - this.color, - this.bold, - this.regular, - this.medium, - this.allowExpand = true, - this.italic= false, - this.textAlign, - this.maxLength = 60, - this.maxLines, - this.readMore = false, - this.style, - this.fontSize, - this.fontWeight, - this.margin, - this.marginBottom, - this.marginLeft, - this.marginRight, - this.marginTop, - this.decoration, - this.heightFactor,}) - : super(key: key); + Texts( + this.text, { + Key? key, + this.variant, + this.color, + this.bold, + this.regular, + this.medium, + this.allowExpand = true, + this.italic = false, + this.textAlign, + this.maxLength = 60, + this.maxLines, + this.readMore = false, + this.style, + this.fontSize, + this.fontWeight, + this.margin, + this.marginBottom, + this.marginLeft, + this.marginRight, + this.marginTop, + this.decoration, + this.heightFactor, + }) : super(key: key); @override _TextsState createState() => _TextsState(); @@ -172,27 +174,28 @@ class _TextsState extends State { TextStyle? _getFontStyle() { switch (widget.style) { case "headline2": - return Theme.of(context).textTheme.headline2; + // return Theme.of(context).textTheme.headline2; + return TextStyle(color: Colors.white); case "headline3": - return Theme.of(context).textTheme.headline3; + return TextStyle(color: Colors.white); case "headline4": - return Theme.of(context).textTheme.headline4; + return TextStyle(color: Colors.white); case "headline5": - return Theme.of(context).textTheme.headline5; + return TextStyle(color: Colors.white); case "headline6": - return Theme.of(context).textTheme.headline6; + return TextStyle(color: Colors.white); case "bodyText2": - return Theme.of(context).textTheme.bodyText2; + return TextStyle(color: Colors.white); case "bodyText_15": - return Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: 15.0); + return TextStyle(color: Colors.white, fontSize: 15.0); case "bodyText1": - return Theme.of(context).textTheme.bodyText1; + return TextStyle(color: Colors.white); case "caption": - return Theme.of(context).textTheme.caption; + return TextStyle(color: Colors.white); case "overline": - return Theme.of(context).textTheme.overline; + return TextStyle(color: Colors.white); case "button": - return Theme.of(context).textTheme.button; + return TextStyle(color: Colors.white); default: return TextStyle(); } @@ -205,39 +208,25 @@ class _TextsState extends State { Stack( children: [ Text( - !hidden - ? text - : (text.substring( - 0, - text.length > widget.maxLength! - ? widget.maxLength - : text.length)), + !hidden ? text : (text.substring(0, text.length > widget.maxLength! ? widget.maxLength : text.length)), textAlign: widget.textAlign, - overflow: widget.maxLines != null - ? ((widget.maxLines! > 1) - ? TextOverflow.fade - : TextOverflow.ellipsis) - : null, + overflow: widget.maxLines != null ? ((widget.maxLines! > 1) ? TextOverflow.fade : TextOverflow.ellipsis) : null, maxLines: widget.maxLines ?? null, style: widget.style != null ? _getFontStyle()!.copyWith( fontStyle: widget.italic! ? FontStyle.italic : null, - color: widget.color != null - ? widget.color - : Theme.of(context).textTheme.bodyText1!.color, + color: widget.color != null ? widget.color : Colors.black, fontWeight: widget.fontWeight ?? _getFontWeight(), ) : TextStyle( height: widget.heightFactor, decoration: widget.decoration, fontStyle: widget.italic! ? FontStyle.italic : null, - color: widget.color ?? - Theme.of(context).textTheme.bodyText1!.color, + color: widget.color ?? Colors.black, fontSize: widget.fontSize ?? _getFontSize(), letterSpacing: widget.variant == "overline" ? 1 : null, fontWeight: widget.fontWeight ?? _getFontWeight(), - fontFamily: - projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), ), if (widget.readMore! && text.length > widget.maxLength! && hidden) Positioned( @@ -247,8 +236,8 @@ class _TextsState extends State { child: Container( decoration: BoxDecoration( gradient: LinearGradient(colors: [ - Theme.of(context).backgroundColor, - Theme.of(context).backgroundColor.withOpacity(0), + CustomColors.white, + CustomColors.white.withOpacity(0), ], begin: Alignment.bottomCenter, end: Alignment.topCenter), ), height: 30.0, @@ -256,9 +245,7 @@ class _TextsState extends State { ) ], ), - if (widget.allowExpand! && - widget.readMore! && - text.length > widget.maxLength!) + if (widget.allowExpand! && widget.readMore! && text.length > widget.maxLength!) Padding( padding: EdgeInsets.only(top: 8.0, right: 8.0, bottom: 8.0), child: InkWell( diff --git a/lib/widgets/dialogs/confirm_dialog.dart b/lib/widgets/dialogs/confirm_dialog.dart index a493f14e..1da92ac5 100644 --- a/lib/widgets/dialogs/confirm_dialog.dart +++ b/lib/widgets/dialogs/confirm_dialog.dart @@ -73,7 +73,9 @@ class Mdialog extends StatelessWidget { Text( // title != null ? title : TranslationBase.of(context).confirm, title!, + style: TextStyle( + fontSize: 24, letterSpacing: -0.94, fontWeight: FontWeight.w600, @@ -82,6 +84,7 @@ class Mdialog extends StatelessWidget { Text( // this.confirmMessage, description!, + style: TextStyle( fontSize: 12, letterSpacing: -0.48, @@ -101,7 +104,7 @@ class Mdialog extends StatelessWidget { child: Container( decoration: containerRadius(CustomColors.accentColor, 12), padding: EdgeInsets.only(top: 8,bottom: 8), - child: Center(child: Texts(cancelText, variant: "caption3", color: CustomColors.white,)), + child: Center(child: Texts(cancelText, textAlign: TextAlign.center, variant: "caption3", color: CustomColors.white,)), ), ), ), @@ -115,6 +118,7 @@ class Mdialog extends StatelessWidget { child: Center( child: Texts( okText, + textAlign: TextAlign.center, color: Colors.white, variant: "caption3", ), diff --git a/lib/widgets/dialogs/location_selection_dialog.dart b/lib/widgets/dialogs/location_selection_dialog.dart new file mode 100644 index 00000000..9ffb2635 --- /dev/null +++ b/lib/widgets/dialogs/location_selection_dialog.dart @@ -0,0 +1,261 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/radiology_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; + +import '../../uitl/translations_delegate_base.dart'; + +class LocationSelectionDialog extends StatelessWidget { + final List data; + final Function(int)? onValueSelected; + final int? selectedIndex; + final bool isArabic; + + const LocationSelectionDialog({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic}); + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: LocationDialogBody( + isArabic: isArabic, + data: data, + onValueSelected: onValueSelected, + selectedIndex: selectedIndex, + )); + } +} + +class LocationDialogBody extends StatefulWidget { + final List data; + final Function(int)? onValueSelected; + final int? selectedIndex; + final bool isArabic; + + const LocationDialogBody({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic}); + + @override + State createState() => _LocationDialogBodyState(); +} + +class _LocationDialogBodyState extends State { + bool isListVisible = false; + int currentlySelected = -1; + + @override + Widget build(BuildContext context) { + return isListVisible + ? LocationListExpandedBody( + isArabic: widget.isArabic, + data: widget.data, + onItemClick: (data) { + if (data.isEmpty) return; + var selected = widget.data.indexWhere( + (item) => item.name == data, + ); + + if (selected == -1) return; + setState(() { + currentlySelected = selected; + isListVisible = false; + }); + }, + ) + : LocationListWrapBody( + onConfirmClicked: () { + widget.onValueSelected?.call(currentlySelected); + }, + onTextBoxClicked: () { + setState(() { + isListVisible = true; + }); + }, + selectedText: currentlySelected == -1 ? "" : widget.data[currentlySelected].name ?? ""); + } +} + +class LocationListExpandedBody extends StatefulWidget { + final List data; + final Function(String) onItemClick; + final bool isArabic; + + const LocationListExpandedBody({super.key, required this.data, required this.onItemClick, required this.isArabic}); + + @override + State createState() => _LocationListExpandedBodyState(); +} + +class _LocationListExpandedBodyState extends State { + List tempListData = []; + TextEditingController controller = new TextEditingController(); + + @override + void initState() { + super.initState(); + setState(() { + tempListData.addAll(widget.data); + }); + } + + @override + Widget build(BuildContext context) { + return Container( + child: Padding( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SelectBranchHeader(), + SizedBox( + height: 8, + ), + TextField( + controller: controller, + onChanged: (v) { + tempListData.clear(); + if (v.length > 0) { + for (int i = 0; i < widget.data.length; i++) { + if (widget.data[i].name?.toLowerCase().contains(v.toLowerCase()) == true) { + tempListData.add(widget.data[i]); + } + } + } else { + tempListData.addAll(widget.data); + } + setState(() {}); + }, + decoration: InputDecoration( + hintStyle: TextStyle(fontSize: 12), + hintText: TranslationBase.of(context).searchByBranch, + suffixIcon: Icon(Icons.search), + contentPadding: EdgeInsets.symmetric(vertical: 9, horizontal: 14), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + borderSide: BorderSide( + color: Colors.grey, // Normal border color + width: 1.0, + ), + ), + ), + ), + SizedBox( + height: 16, + ), + ListView.builder( + itemCount: tempListData.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(bottom: 8), + child: SizedBox( + height: 24, + child: InkWell( + onTap: () { + widget.onItemClick(tempListData[index].name ?? ""); + }, + child: Text( + "${widget.isArabic ? tempListData[index].nameN : tempListData[index].name ?? ""}", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black, letterSpacing: -0.96), + ), + ), + ), + ); + }) + ], + ), + ), + ); + } +} + +class LocationListWrapBody extends StatelessWidget { + final VoidCallback? onConfirmClicked; + final VoidCallback? onTextBoxClicked; + final String selectedText; + + const LocationListWrapBody({super.key, this.onConfirmClicked, this.onTextBoxClicked, required this.selectedText}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SelectBranchHeader(), + SizedBox( + height: 24, + ), + ListTile( + onTap: () { + onTextBoxClicked?.call(); + }, + title: Text( + TranslationBase.of(context).selectBranch, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black, letterSpacing: -0.96), + ), + subtitle: selectedText.isEmpty + ? null + : Text( + selectedText, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black, letterSpacing: -0.96), + ), + trailing: Icon( + Icons.arrow_drop_down_outlined, + color: Colors.black, + ), + shape: RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 1), + borderRadius: BorderRadius.circular(8), + ), + ), + SizedBox( + height: 24, + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).confirm, + () { + Navigator.pop(context); + onConfirmClicked?.call(); + }, + color: CustomColors.accentColor, + ), + ), + ], + ), + ], + ), + ); + } +} + +class SelectBranchHeader extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).selectBranch, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black, letterSpacing: -0.96), + ), + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Icon(Icons.close), + )) + ], + ); + } +} diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 1b525e21..f82047a5 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -1,4 +1,5 @@ import 'dart:io' show Platform; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/config.dart'; @@ -144,20 +145,33 @@ class _AppDrawerState extends State { (user != null && projectProvider!.isLogin) ? user!.firstName! + ' ' + user!.lastName! : TranslationBase.of(context).cantSeeProfile, style: TextStyle(color: Color(0xff2E303A), fontWeight: FontWeight.bold, fontSize: 20, letterSpacing: -1.2, height: 35 / 20), ), - Text( + AutoSizeText( (user != null && projectProvider!.isLogin) ? TranslationBase.of(context).fileNumber + ": " + user!.patientID.toString() : TranslationBase.of(context).loginRegisterNow, + maxLines: 1, + minFontSize: 10, style: TextStyle( - color: Color(0xff2E303A), - fontSize: 16, - letterSpacing: -0.96, - height: 1, + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, ), ), + // Text( + // (user != null && projectProvider!.isLogin) + // ? TranslationBase.of(context).fileNumber + ": " + user!.patientID.toString() + // : TranslationBase.of(context).loginRegisterNow, + // style: TextStyle( + // color: Color(0xff2E303A), + // fontSize: 16, + // letterSpacing: -0.96, + // height: 1, + // ), + // ), mHeight(20.0), (user != null && projectProvider!.isLogin) - ? Image.network("https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${user!.patientID.toString()}", fit: BoxFit.fill, height: 73.5, width: 73.5) + ? Image.network("https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${user!.patientID.toString()}", fit: BoxFit.fill, height: 70, width: 70) : Container(), ], ), @@ -204,8 +218,8 @@ class _AppDrawerState extends State { child: DrawerItem(TranslationBase.of(context).family, SvgPicture.asset("assets/images/new/family_files.svg"), isImageIcon: true, bottomLine: false, - textColor: Theme.of(context).textTheme.bodyText1!.color, - iconColor: Theme.of(context).textTheme.bodyText1!.color, + textColor: CustomColors.black, + iconColor: CustomColors.black, sideArrow: true, letterSpacing: -0.84, projectProvider: projectProvider), @@ -705,7 +719,7 @@ class _AppDrawerState extends State { // result.list.cRSVerificationStatus = result['CRSVerificationStatus']; await this.sharedPref.setString(APP_LANGUAGE, currentLang); await this.sharedPref.setString(BLOOD_TYPE, bloodType); - await this.sharedPref.setInt(LAST_LOGIN, loginType ?? 1 ); + await this.sharedPref.setInt(LAST_LOGIN, loginType ?? 1); await this.sharedPref.setObject(MAIN_USER, mainUser); await this.sharedPref.setObject(USER_PROFILE, result.list); await this.sharedPref.setObject(FAMILY_FILE, familyFile); diff --git a/lib/widgets/drawer/drawer_item_widget.dart b/lib/widgets/drawer/drawer_item_widget.dart index af0d81e9..2af437e4 100644 --- a/lib/widgets/drawer/drawer_item_widget.dart +++ b/lib/widgets/drawer/drawer_item_widget.dart @@ -1,7 +1,9 @@ import 'dart:ui'; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -52,7 +54,7 @@ class _DrawerItemState extends State { ? widget.icon : Icon( widget.icon, - color: widget.iconColor == null ? Theme.of(context).textTheme.bodyText1?.color : widget.iconColor, + color: widget.iconColor == null ? CustomColors.black : widget.iconColor, size: SizeConfig.imageSizeMultiplier! * 5, )), Expanded( @@ -60,13 +62,24 @@ class _DrawerItemState extends State { child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ - AppText( + AutoSizeText( widget.title!, - fontWeight: FontWeight.w600, - fontSize: widget.fontSize, - height: widget.fontHeight, - letterSpacing: widget.letterSpacing, + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), ), + // AppText( + // widget.title!, + // fontWeight: FontWeight.w600, + // fontSize: widget.fontSize, + // height: widget.fontHeight, + // letterSpacing: widget.letterSpacing, + // ), widget.count ?? SizedBox(), ], ), diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart index a04b5f03..6f61ac8a 100644 --- a/lib/widgets/in_app_browser/InAppBrowser.dart +++ b/lib/widgets/in_app_browser/InAppBrowser.dart @@ -138,7 +138,7 @@ class MyInAppBrowser extends InAppBrowser { openPackagesPaymentBrowser({required int customer_id, required int order_id}) { paymentType = _PAYMENT_TYPE.PACKAGES; var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id'; - this.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(full_url)), options: _InAppBrowserOptions); + this.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(full_url))), options: _InAppBrowserOptions); } openPaymentBrowser(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID, @@ -190,7 +190,7 @@ class MyInAppBrowser extends InAppBrowser { String url = "https://hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // Prod // String url = "https://uat.hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // UAT // safariBrowser.open(url: Uri.parse(url)); - this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions); + this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions); }).catchError((err) { print(err); if (context != null) GifLoaderDialogUtils.hideDialog(context); @@ -218,7 +218,7 @@ class MyInAppBrowser extends InAppBrowser { tamaraRequestModel.customerName = patientName; tamaraRequestModel.fileNumber = patientID.toString(); tamaraRequestModel.patientOutSA = authenticatedUser.outSA == 1 ? true : false; - tamaraRequestModel.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + tamaraRequestModel.deviceToken = await AppSharedPreferences().getStringWithDefaultValue(PUSH_TOKEN, ""); tamaraRequestModel.latitude = this.lat.toString(); tamaraRequestModel.longitude = this.long.toString(); tamaraRequestModel.serviceID = servID; @@ -233,7 +233,7 @@ class MyInAppBrowser extends InAppBrowser { appoNo, clinicID, doctorID, "", installments) .then((value) { paymentType = _PAYMENT_TYPE.PATIENT; - this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); + this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions); }); }).catchError((err) { print(err); @@ -245,7 +245,7 @@ class MyInAppBrowser extends InAppBrowser { clinicID, doctorID) .then((value) { paymentType = _PAYMENT_TYPE.PATIENT; - this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); + this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions); }); } } @@ -258,16 +258,16 @@ class MyInAppBrowser extends InAppBrowser { // getPatientData(); generatePharmacyURL(order, amount, orderDesc, transactionID, emailId, paymentMethod, patientName, patientID, authenticatedUser).then((value) { if (order.customValuesXml!.contains("ApplePay")) { - safariBrowser.open(url: Uri.parse(value)); + safariBrowser.open(url: WebUri.uri(Uri.parse(value))); } else { - this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); + this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions); } }); } openBrowser(String url) { this.browser = browser; - this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions); + this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions); } Future generateURL(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID, @@ -290,8 +290,8 @@ class MyInAppBrowser extends InAppBrowser { form = form.replaceFirst('PATIENT_TYPE_ID', patientData == null ? patientType.toString() : "1"); Platform.isIOS - ? form = form.replaceFirst('DEVICE_TOKEN', await AppSharedPreferences().getString(PUSH_TOKEN) + "," + await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN)) - : form = form.replaceFirst('DEVICE_TOKEN', await sharedPref.getString(PUSH_TOKEN) ?? ""); + ? form = form.replaceFirst('DEVICE_TOKEN', await AppSharedPreferences().getStringWithDefaultValue(PUSH_TOKEN, "") + "," + await AppSharedPreferences().getStringWithDefaultValue(ONESIGNAL_APNS_TOKEN, "")) + : form = form.replaceFirst('DEVICE_TOKEN', await sharedPref.getStringWithDefaultValue(PUSH_TOKEN, "") ?? ""); // form = form.replaceFirst('DEVICE_TOKEN', await AppSharedPreferences().getString(PUSH_TOKEN) + "," + await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN)); // form = form.replaceFirst('DEVICE_TOKEN', await sharedPref.getString(PUSH_TOKEN)); @@ -489,7 +489,7 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser { } @override - void onCompletedInitialLoad() { + void onCompletedInitialLoad(bool? didLoadSuccessfully) { print("ChromeSafari browser initial load completed"); onLoadStartCallback!("ApplePay"); } diff --git a/lib/widgets/input/text_field.dart b/lib/widgets/input/text_field.dart index be6c9989..db467112 100644 --- a/lib/widgets/input/text_field.dart +++ b/lib/widgets/input/text_field.dart @@ -1,10 +1,10 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class NumberTextInputFormatter extends TextInputFormatter { @override - TextEditingValue formatEditUpdate( - TextEditingValue oldValue, TextEditingValue newValue) { + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { final int newTextLength = newValue.text.length; int selectionIndex = newValue.selection.end; int usedSubstringIndex = 0; @@ -26,8 +26,7 @@ class NumberTextInputFormatter extends TextInputFormatter { if (newValue.selection.end >= 10) selectionIndex++; } // Dump the rest. - if (newTextLength >= usedSubstringIndex) - newText.write(newValue.text.substring(usedSubstringIndex)); + if (newTextLength >= usedSubstringIndex) newText.write(newValue.text.substring(usedSubstringIndex)); return TextEditingValue( text: newText.toString(), selection: TextSelection.collapsed(offset: selectionIndex), @@ -63,7 +62,7 @@ class TextFields extends StatefulWidget { this.borderOnlyError = false, this.onSaved, this.onSuffixTap, - this.readOnly= false, + this.readOnly = false, this.maxLength, this.prefixIcon, this.bare = false, @@ -164,19 +163,14 @@ class _TextFieldsState extends State { view = true; }); }, - child: Icon(Icons.remove_red_eye_sharp, - size: 24.0, color: Colors.grey[500]), + child: Icon(Icons.remove_red_eye_sharp, size: 24.0, color: Colors.grey[500]), ), ); default: if (widget.suffixIcon != null) return InkWell( onTap: widget.onSuffixTap, - child: Icon(widget.suffixIcon, - size: 22.0, - color: widget.suffixIconColor != null - ? widget.suffixIconColor - : Colors.grey[500]), + child: Icon(widget.suffixIcon, size: 22.0, color: widget.suffixIconColor != null ? widget.suffixIconColor : Colors.grey[500]), ); else return SizedBox(); @@ -203,10 +197,7 @@ class _TextFieldsState extends State { // color: Color.fromRGBO(70, 68, 167, focus ? 0.20 : 0), // offset: Offset(0.0, 13.0), // blurRadius: focus ? 34.0 : 12.0) - BoxShadow( - color: Color.fromRGBO(110, 68, 80, focus! ? 0.20 : 0), - offset: Offset(0.0, 13.0), - blurRadius: focus! ? 34.0 : 12.0) + BoxShadow(color: Color.fromRGBO(110, 68, 80, focus! ? 0.20 : 0), offset: Offset(0.0, 13.0), blurRadius: focus! ? 34.0 : 12.0) ]), child: TextFormField( keyboardAppearance: Theme.of(context).brightness, @@ -234,10 +225,11 @@ class _TextFieldsState extends State { autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context) - .textTheme - .bodyText1! - .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + // style: Theme.of(context) + // .textTheme + // .bodyText1! + // .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ FilteringTextInputFormatter.digitsOnly, @@ -252,41 +244,18 @@ class _TextFieldsState extends State { fontWeight: widget.fontWeight, color: widget.hintColor ?? Theme.of(context).hintColor, ), - contentPadding: widget.padding != null - ? widget.padding - : EdgeInsets.symmetric( - vertical: (widget.bare! && !widget.keepPadding!) ? 0.0 : 10.0, - horizontal: 16.0), + contentPadding: widget.padding != null ? widget.padding : EdgeInsets.symmetric(vertical: (widget.bare! && !widget.keepPadding!) ? 0.0 : 10.0, horizontal: 16.0), filled: true, - fillColor: widget.bare! - ? Colors.transparent - : Theme.of(context).backgroundColor, + fillColor: widget.bare! ? Colors.transparent : CustomColors.white, suffixIcon: _buildSuffixIcon(), prefixIcon: widget.prefixIcon, - errorStyle: TextStyle( - fontSize: 14.0, - fontWeight: widget.fontWeight, - height: widget.borderOnlyError! ? 0.0 : null), + errorStyle: TextStyle(fontSize: 14.0, fontWeight: widget.fontWeight, height: widget.borderOnlyError! ? 0.0 : null), errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(widget.bare! ? 0.0 : 0.5), - width: 1.0), - borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), + borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(widget.bare! ? 0.0 : 0.5), width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(widget.bare! ? 0.0 : 0.5), - width: 1.0), - borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1.0), - borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1.0), - borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), + borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(widget.bare! ? 0.0 : 0.5), width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), + focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), + disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0), diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart index b2c7b34a..8790d1b3 100644 --- a/lib/widgets/others/app_expandable_notifier.dart +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -24,6 +24,9 @@ class AppExpandableNotifier extends StatefulWidget { var controller = new ExpandableController(); bool isTitleSingleLine; bool isDisabled = false; + bool isDoctorSearchResult = false; + final String? projectTitleTop; + final String? projectTitleBottom; AppExpandableNotifier( {this.headerWidget, @@ -35,14 +38,15 @@ class AppExpandableNotifier extends StatefulWidget { this.hasCounter = false, this.counter = "0", this.widgetColor = Colors.white, - this.isDisabled = false}); + this.isDisabled = false, + this.isDoctorSearchResult = false, + this.projectTitleTop = "", + this.projectTitleBottom = ""}); _AppExpandableNotifier createState() => _AppExpandableNotifier(); } class _AppExpandableNotifier extends State { - late ProjectViewModel projectViewModel; - @override void initState() { setState(() { @@ -56,13 +60,19 @@ class _AppExpandableNotifier extends State { @override Widget build(BuildContext context) { - projectViewModel = Provider.of(context); - String _mainTitle = (widget.title ?? TranslationBase.of(context).details).trim(); - String _title = _mainTitle.contains(" ") ? (projectViewModel.isArabic ? (_mainTitle.split(" ").length < 1 ? _mainTitle : _mainTitle.split(" ")[1]) : _mainTitle.split(" ")[0]) : _mainTitle; - // String _title = _mainTitle.split(" ")[0]; - String _subTitle = _mainTitle.replaceAll(_title, "").trim(); + String _title = ""; + String _subTitle = ""; + if (widget.isDoctorSearchResult) { + _title = widget.projectTitleTop ?? (context.read().isArabic ? (_mainTitle.split(" ").length < 1 ? _mainTitle : _mainTitle.split(" ")[1]) : _mainTitle.split(" ")[0]); + _subTitle = widget.projectTitleBottom ?? _mainTitle.replaceAll(_title, "").trim(); + } else { + _title = + _mainTitle.contains(" ") ? (context.read().isArabic ? (_mainTitle.split(" ").length < 1 ? _mainTitle : _mainTitle.split(" ")[1]) : _mainTitle.split(" ")[0]) : _mainTitle; + // String _title = _mainTitle.split(" ")[0]; + _subTitle = _mainTitle.replaceAll(_title, "").trim(); + } if (_subTitle.length < 1) { _subTitle = double.tryParse(_subTitle) != null ? _title : _title.toLowerCase().capitalizeFirstofEach; _title = ""; @@ -70,6 +80,7 @@ class _AppExpandableNotifier extends State { _subTitle = double.tryParse(_subTitle) == null ? _subTitle : _subTitle.toLowerCase().capitalizeFirstofEach; _title = double.tryParse(_subTitle) == null ? _title : _title.toLowerCase().capitalizeFirstofEach; } + return ExpandableNotifier( child: Container( color: widget.widgetColor != null ? widget.widgetColor : Colors.white, @@ -82,7 +93,7 @@ class _AppExpandableNotifier extends State { scrollOnExpand: true, scrollOnCollapse: false, child: ExpandablePanel( - // hasIcon: false, + // hasIcon: false, theme: const ExpandableThemeData( hasIcon: false, headerAlignment: ExpandablePanelHeaderAlignment.center, diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 883e2de3..1103b31b 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -494,7 +494,8 @@ class AppBarWidgetState extends State { // headline6: TextStyle(color: Theme.of(context).textTheme.headline1.color, fontWeight: FontWeight.bold), // ), title: Text(widget.authenticatedUserObject.isLogin || !widget.isShowDecPage ? widget.appBarTitle!.toUpperCase() : TranslationBase.of(context).serviceInformationTitle, - style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.headline1!.color, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans')), + // style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.headline1!.color, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans')), + style: TextStyle(fontWeight: FontWeight.bold, color: CustomColors.white, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans')), leading: Builder( builder: (BuildContext context) { return ArrowBack( diff --git a/lib/widgets/others/not_auh_page.dart b/lib/widgets/others/not_auh_page.dart index 063878bb..6389ba00 100644 --- a/lib/widgets/others/not_auh_page.dart +++ b/lib/widgets/others/not_auh_page.dart @@ -125,207 +125,207 @@ class _NotAutPageState extends State { ), ); - Scaffold( - backgroundColor: Color(0xfff8f8f8), - resizeToAvoidBottomInset: false, - appBar: AppBar( - backgroundColor: Colors.transparent, - leading: IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Color(0xff2B353E), - onPressed: () => Navigator.pop(context), - ), - ), - body: Padding( - padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), - child: Column(children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - physics: BouncingScrollPhysics(), - children: [ - SizedBox(height: 12), - if (widget.icon != null) - Align( - alignment: Alignment.centerLeft, - child: SvgPicture.asset( - widget.icon!, - height: 35, - width: 35, - ), - ), - SizedBox(height: 16), - Text( - widget.title, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 23 / 24), - ), - Text( - widget.description!, - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56, height: 21 / 14), - ), - SizedBox( - height: 14, - ), - if (!projectViewModel.isInternetConnection) - Center( - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.55, - width: MediaQuery.of(context).size.width * 0.50, - child: Image.asset(projectViewModel.isArabic ? 'assets/images/Wifi-AR.png' : 'assets/images/wifi-EN.png'), - ), - ), - if (projectViewModel.isInternetConnection && widget.imagesInfo != null) - CarouselSlider( - items: widget.imagesInfo?.map((image) { - return Builder( - builder: (BuildContext context) { - return SizedBox( - width: MediaQuery.of(context).size.width * 0.50, - child: image.isAsset! ? Image.asset(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!) : Image.network(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!)); - }, - ); - }).toList(), - options: CarouselOptions( - height: MediaQuery.of(context).size.height * 0.55, - autoPlay: widget.imagesInfo!.length > 1, - viewportFraction: 1.0, - ), - ), - ], - ), - ), - SizedBox( - height: 43, - width: double.infinity, - child: TextButton( - onPressed: () { - loginCheck(context); - }, - child: Text( - TranslationBase.of(context).loginregister, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), - ), - style: TextButton.styleFrom( - backgroundColor: Color(0xffD02127), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(6), - ), - )), - ), - ]), - ), - ); - - return Scaffold( - body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - widget.title ?? 'Service', - fontWeight: FontWeight.w800, - fontSize: 25, - bold: true, - color: Color(0xff60686b), - ), - SizedBox( - height: 12, - ), - Texts( - widget.description ?? 'Description', - fontWeight: FontWeight.normal, - fontSize: 17, - ), - if (widget.infoList != null) - SizedBox( - height: 12, - ), - if (widget.infoList != null) - ...List.generate( - widget.infoList!.length, - (index) => Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - width: 40, - height: 40, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Theme.of(context).primaryColor), - child: Center( - child: Texts( - '${index + 1}', - color: Colors.white, - ), - ), - ), - SizedBox( - width: 6, - ), - Expanded(child: Texts('${widget.infoList![index]}')) - ], - ), - SizedBox( - height: 12, - ), - ], - ), - ), - ), - SizedBox( - height: 22, - ), - if (!projectViewModel.isInternetConnection) - Center( - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.55, - width: MediaQuery.of(context).size.width * 0.50, - child: Image.asset(projectViewModel.isArabic ? 'assets/images/Wifi-AR.png' : 'assets/images/wifi-EN.png'), - ), - ), - if (projectViewModel.isInternetConnection && widget.imagesInfo != null) - CarouselSlider( - items: widget.imagesInfo!.map((image) { - return Builder( - builder: (BuildContext context) { - return SizedBox( - width: MediaQuery.of(context).size.width * 0.50, - child: image.isAsset! ? Image.asset(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!) : Image.network(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!)); - }, - ); - }).toList(), - options: CarouselOptions( - height: MediaQuery.of(context).size.height * 0.55, - autoPlay: widget.imagesInfo!.length > 1, - viewportFraction: 1.0, - ), - ), - 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: () { - loginCheck(context); - }, - label: TranslationBase.of(context).serviceInformationButton, - textColor: Theme.of(context).backgroundColor), - ), - ], - ), - ), - ); + // Scaffold( + // backgroundColor: Color(0xfff8f8f8), + // resizeToAvoidBottomInset: false, + // appBar: AppBar( + // backgroundColor: Colors.transparent, + // leading: IconButton( + // icon: Icon(Icons.arrow_back_ios), + // color: Color(0xff2B353E), + // onPressed: () => Navigator.pop(context), + // ), + // ), + // body: Padding( + // padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + // child: Column(children: [ + // Expanded( + // child: ListView( + // padding: EdgeInsets.zero, + // physics: BouncingScrollPhysics(), + // children: [ + // SizedBox(height: 12), + // if (widget.icon != null) + // Align( + // alignment: Alignment.centerLeft, + // child: SvgPicture.asset( + // widget.icon!, + // height: 35, + // width: 35, + // ), + // ), + // SizedBox(height: 16), + // Text( + // widget.title, + // style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 23 / 24), + // ), + // Text( + // widget.description!, + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56, height: 21 / 14), + // ), + // SizedBox( + // height: 14, + // ), + // if (!projectViewModel.isInternetConnection) + // Center( + // child: SizedBox( + // height: MediaQuery.of(context).size.height * 0.55, + // width: MediaQuery.of(context).size.width * 0.50, + // child: Image.asset(projectViewModel.isArabic ? 'assets/images/Wifi-AR.png' : 'assets/images/wifi-EN.png'), + // ), + // ), + // if (projectViewModel.isInternetConnection && widget.imagesInfo != null) + // CarouselSlider( + // items: widget.imagesInfo?.map((image) { + // return Builder( + // builder: (BuildContext context) { + // return SizedBox( + // width: MediaQuery.of(context).size.width * 0.50, + // child: image.isAsset! ? Image.asset(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!) : Image.network(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!)); + // }, + // ); + // }).toList(), + // options: CarouselOptions( + // height: MediaQuery.of(context).size.height * 0.55, + // autoPlay: widget.imagesInfo!.length > 1, + // viewportFraction: 1.0, + // ), + // ), + // ], + // ), + // ), + // SizedBox( + // height: 43, + // width: double.infinity, + // child: TextButton( + // onPressed: () { + // loginCheck(context); + // }, + // child: Text( + // TranslationBase.of(context).loginregister, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), + // ), + // style: TextButton.styleFrom( + // backgroundColor: Color(0xffD02127), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(6), + // ), + // )), + // ), + // ]), + // ), + // ); + // + // return Scaffold( + // body: SingleChildScrollView( + // padding: EdgeInsets.all(12), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Texts( + // widget.title ?? 'Service', + // fontWeight: FontWeight.w800, + // fontSize: 25, + // bold: true, + // color: Color(0xff60686b), + // ), + // SizedBox( + // height: 12, + // ), + // Texts( + // widget.description ?? 'Description', + // fontWeight: FontWeight.normal, + // fontSize: 17, + // ), + // if (widget.infoList != null) + // SizedBox( + // height: 12, + // ), + // if (widget.infoList != null) + // ...List.generate( + // widget.infoList!.length, + // (index) => Container( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Row( + // children: [ + // Container( + // width: 40, + // height: 40, + // decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Theme.of(context).primaryColor), + // child: Center( + // child: Texts( + // '${index + 1}', + // color: Colors.white, + // ), + // ), + // ), + // SizedBox( + // width: 6, + // ), + // Expanded(child: Texts('${widget.infoList![index]}')) + // ], + // ), + // SizedBox( + // height: 12, + // ), + // ], + // ), + // ), + // ), + // SizedBox( + // height: 22, + // ), + // if (!projectViewModel.isInternetConnection) + // Center( + // child: SizedBox( + // height: MediaQuery.of(context).size.height * 0.55, + // width: MediaQuery.of(context).size.width * 0.50, + // child: Image.asset(projectViewModel.isArabic ? 'assets/images/Wifi-AR.png' : 'assets/images/wifi-EN.png'), + // ), + // ), + // if (projectViewModel.isInternetConnection && widget.imagesInfo != null) + // CarouselSlider( + // items: widget.imagesInfo!.map((image) { + // return Builder( + // builder: (BuildContext context) { + // return SizedBox( + // width: MediaQuery.of(context).size.width * 0.50, + // child: image.isAsset! ? Image.asset(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!) : Image.network(projectViewModel.isArabic! ? image.imageAr! : image.imageEn!)); + // }, + // ); + // }).toList(), + // options: CarouselOptions( + // height: MediaQuery.of(context).size.height * 0.55, + // autoPlay: widget.imagesInfo!.length > 1, + // viewportFraction: 1.0, + // ), + // ), + // 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: () { + // loginCheck(context); + // }, + // label: TranslationBase.of(context).serviceInformationButton, + // textColor: Theme.of(context).backgroundColor), + // ), + // ], + // ), + // ), + // ); } loginCheck(context) async { diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/otp/sms-popup.dart index c87dceeb..b6a89573 100644 --- a/lib/widgets/otp/sms-popup.dart +++ b/lib/widgets/otp/sms-popup.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; @@ -211,12 +212,12 @@ class SMSOTP { errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/widgets/text/app_texts_widget.dart b/lib/widgets/text/app_texts_widget.dart index 01dce651..0d1e6477 100644 --- a/lib/widgets/text/app_texts_widget.dart +++ b/lib/widgets/text/app_texts_widget.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -62,7 +63,7 @@ class _AppTextState extends State { overflow: TextOverflow.clip, style: TextStyle( - color: widget.color == null ? Theme.of(context).textTheme.bodyText1!.color : widget.color, + color: widget.color == null ? CustomColors.black : widget.color, fontWeight: widget.fontWeight, fontSize: widget.fontSize ?? (SizeConfig.textMultiplier! * 2), height: widget.height, diff --git a/pubspec.yaml b/pubspec.yaml index 0e9b2bd6..7b43a711 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: diplomaticquarterapp description: A new Flutter application. -version: 4.5.061+4050061 +version: 4.5.073+4050073 environment: sdk: ">=3.0.0 <3.13.0" @@ -13,9 +13,11 @@ dependencies: # Localizations flutter_localizations: sdk: flutter - intl: ^0.18.1 +# intl: ^0.18.1 + intl: ^0.19.0 - webview_flutter: ^2.0.4 +# webview_flutter: ^2.0.4 + webview_flutter: ^4.8.0 # http client http: ^0.13.4 @@ -32,7 +34,9 @@ dependencies: get_it: ^7.2.0 #Google Fit & Apple HealthKit - health: ^3.0.3 +# health: ^3.0.3 + health: ^11.1.0 +# pedometer: ^4.0.2 #chart fl_chart: ^0.64.0 @@ -97,16 +101,17 @@ dependencies: flutter_rating_bar: ^4.0.1 # Calendar - syncfusion_flutter_calendar: ^23.1.42 + # syncfusion_flutter_calendar: ^23.1.42 + syncfusion_flutter_calendar: ^24.1.47 # SVG Images flutter_svg: ^2.0.8 #Calendar Events - manage_calendar_events: ^2.0.3 + manage_calendar_events: 2.0.3 #InAppBrowser - flutter_inappwebview: ^5.8.0 + flutter_inappwebview: ^6.1.5 #Circular progress bar for reverse timer circular_countdown_timer: ^0.2.0 @@ -121,7 +126,7 @@ dependencies: flutter_datetime_picker_plus: ^2.1.0 carousel_pro_nullsafety: ^2.0.0 flutter_local_notifications: any - device_calendar: ^4.3.2 + device_calendar: ^4.3.3 geolocator: ^9.0.2 geocoding: ^2.0.1 jiffy: ^6.2.1 @@ -132,13 +137,15 @@ dependencies: google_maps_place_picker_mb: ^3.0.0 map_launcher: ^3.0.1 flutter_countdown_timer: ^4.1.0 + carousel_slider: ^5.0.0 #Dependencies for video call implementation native_device_orientation: ^1.0.0 - wakelock: ^0.6.2 +# wakelock: ^0.6.2 + wakelock_plus: ^1.1.4 after_layout: ^1.1.0 cached_network_image: ^3.3.0 flutter_tts: ^3.6.1 - vibration: ^1.7.3 +# vibration: ^1.7.3 flutter_nfc_kit: ^3.3.1 #geofencing: any speech_to_text: ^6.1.1 @@ -148,16 +155,16 @@ dependencies: in_app_review: ^2.0.3 badges: ^3.1.2 - flutter_app_icon_badge: ^2.0.0 +# flutter_app_icon_badge: ^2.0.0 # dropdown_search: 5.0.6 - youtube_player_flutter: ^8.1.2 + youtube_player_flutter: ^9.1.0 # shimmer: ^3.0.0 - carousel_slider: ^4.0.0 +# carousel_slider: ^4.0.0 # flutter_staggered_grid_view: ^0.7.0 huawei_hmsavailability: ^6.11.0+301 huawei_location: ^6.11.0+301 - share_plus: ^6.3.4 + share_plus: ^10.0.2 # Marker Animation auto_size_text: ^3.0.0 equatable: ^2.0.3 @@ -167,12 +174,16 @@ dependencies: google_api_availability: ^5.0.0 open_filex: ^4.3.2 path_provider: ^2.0.8 - amazon_payfort: ^1.1.0 + amazon_payfort: ^1.1.3 logger: ^2.0.2+1 network_info_plus: any - flutter_zoom_videosdk: ^1.10.11 + flutter_zoom_videosdk: ^1.11.2 dart_jsonwebtoken: ^2.14.0 + win32: ^5.5.4 + + cloudflare_turnstile: ^2.0.1 + firebase_crashlytics: ^3.0.0 dependency_overrides: