Merge branch 'dev_v3.13.6' into dev_3.13.6_CR5047_LiveCare_Enhancements

# Conflicts:
#	lib/config/config.dart
#	lib/config/localized_values.dart
#	lib/core/service/client/base_app_client.dart
#	lib/pages/conference/zoom/call_screen.dart
#	lib/uitl/translations_delegate_base.dart
merge-update-with-lab-changes
haroon amjad 1 year ago
commit f58e07d789

1
.gitignore vendored

@ -31,6 +31,7 @@ pubspec.lock
.pub-cache/ .pub-cache/
.pub/ .pub/
/build/ /build/
/ios/Frameworks/
# Web related # Web related
lib/generated_plugin_registrant.dart lib/generated_plugin_registrant.dart

@ -56,6 +56,10 @@ android {
compileSdkVersion 34 compileSdkVersion 34
// ndkVersion "24.0.8215888" // ndkVersion "24.0.8215888"
buildFeatures {
viewBinding true
}
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
@ -69,7 +73,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.ejada.hmg" applicationId "com.ejada.hmg"
minSdkVersion 24 minSdkVersion 26
targetSdkVersion 34 targetSdkVersion 34
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
@ -117,15 +121,16 @@ android {
packagingOptions { packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro' exclude 'META-INF/proguard/androidx-annotations.pro'
// pickFirst 'lib/x86/libc++_shared.so' pickFirst 'lib/x86/libc++_shared.so'
// pickFirst 'lib/x86_64/libc++_shared.so' pickFirst 'lib/x86_64/libc++_shared.so'
// pickFirst 'lib/armeabi-v7a/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so'
// pickFirst 'lib/arm64-v8a/libc++_shared.so' pickFirst 'lib/arm64-v8a/libc++_shared.so'
// pickFirst '**/*.so' pickFirst '**/*.so'
} }
compileOptions { compileOptions {
// coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
@ -136,13 +141,15 @@ flutter {
} }
dependencies { dependencies {
// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:21.0.0" implementation "com.google.firebase:firebase-messaging:21.0.0"
// implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{ // 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-javalite'
// exclude group: 'com.google.protobuf',module: 'protobuf-lite' // 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.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' implementation 'com.google.guava:guava:27.0.1-android'
@ -163,11 +170,36 @@ dependencies {
// implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11" // implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11"
// implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '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-core:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" // implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" // implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
implementation "org.jetbrains.anko:anko-commons:0.10.4" 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:2.3.0' //for JVM
implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0'
implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android
@ -177,6 +209,10 @@ dependencies {
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'
implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1' 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" 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'
} }

@ -21,7 +21,7 @@
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
} }
], ],
"services": { "services": {

Binary file not shown.

Binary file not shown.

@ -53,4 +53,20 @@
} }
-dontwarn com.opentok.android.** -dontwarn com.opentok.android.**
-dontwarn com.opentok.otc.** -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.** { *; }

@ -8,21 +8,35 @@
FlutterApplication and put your custom class here. --> FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/> <uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/> <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
<!-- <uses-permission android:name="android.permission.INTERNET" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
<uses-feature android:name="android.hardware.sensor.stepcounter" android:required="false" tools:node="replace"/>
<uses-feature android:name="android.hardware.sensor.stepdetector" android:required="false" tools:node="replace"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@ -42,6 +56,7 @@
<uses-feature android:name="android.hardware.location.network" android:required="false" /> <uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/> <uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<!-- <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />-->
@ -59,13 +74,13 @@
</queries> </queries>
<application <application
android:name=".Application" android:name=".Application"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher_local"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:showOnLockScreen="true" android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait" android:screenOrientation="sensorPortrait"
android:allowBackup="false" android:allowBackup="false"
android:extractNativeLibs="true" android:extractNativeLibs="true"
tools:replace="android:extractNativeLibs" tools:replace="android:extractNativeLibs,android:label"
android:label="Dr. Alhabib"> android:label="Dr. Alhabib">
<meta-data android:name="push_kit_auto_init_enabled" android:value="true" /> <meta-data android:name="push_kit_auto_init_enabled" android:value="true" />

@ -1,21 +1,19 @@
package com.ejada.hmg package com.ejada.hmg
import android.app.NotificationChannel import android.content.Intent
import android.app.NotificationManager import android.content.pm.PackageManager
import android.content.ContentResolver
import android.media.AudioAttributes
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.os.Build import android.os.Build
import android.util.Log
import android.view.WindowManager import android.view.WindowManager
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge
import com.ejada.hmg.utils.* import com.ejada.hmg.utils.*
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() { class MainActivity: FlutterFragmentActivity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge // Create Flutter Platform Bridge
@ -23,6 +21,7 @@ class MainActivity: FlutterFragmentActivity() {
PlatformBridge(flutterEngine, this).create() PlatformBridge(flutterEngine, this).create()
OpenTokPlatformBridge(flutterEngine, this).create() OpenTokPlatformBridge(flutterEngine, this).create()
PenguinInPlatformBridge(flutterEngine, this).create()
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH) // 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") // val time = timeToMillis("04:00:00", "HH:mm:ss")
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
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() { override fun onResume() {

@ -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<String, Any>?
Log.d("TAG", "configureFlutterEngine: $args")
println("args")
args?.let {
PenguinView(
mainActivity,
100,
args,
flutterEngine.dartExecutor.binaryMessenger,
activity = mainActivity,
channel
)
}
}
else -> {
result.notImplemented()
}
}
}
}
}

@ -0,0 +1,28 @@
package com.cloud.diplomaticquarterapp.PermissionManager
import android.Manifest
import android.os.Build
object PermissionHelper {
fun getRequiredPermissions(): Array<String> {
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()
}
}

@ -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<out String>, grantResults: IntArray) {
if (this.requestCode == requestCode) {
val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (allGranted) {
listener.onPermissionGranted()
} else {
listener.onPermissionDenied()
}
}
}
}

@ -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)
}
}

@ -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");
}

@ -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<ResponseBody> = ApiController.getInstance(mContext)
.apiMethods
.getToken(postToken)
// Enqueue the call for asynchronous execution
purposesCall.enqueue(object : Callback<ResponseBody?> {
override fun onResponse(
call: Call<ResponseBody?>,
response: Response<ResponseBody?>
) {
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<ResponseBody?>, t: Throwable) {
apiTokenCallBack.onGetByRefIDError(t.message)
}
})
} catch (error: Exception) {
apiTokenCallBack.onGetByRefIDError("Exception during API call: $error")
}
}
}

@ -0,0 +1,310 @@
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<String, Any>,
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("")
.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 { }
// 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<String, Any?> = 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")
}
}
}

@ -22,7 +22,7 @@ import com.github.kittinunf.fuel.httpPost
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import org.jetbrains.anko.doAsyncResult //import org.jetbrains.anko.doAsyncResult
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject 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 notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher) .setSmallIcon(R.mipmap.ic_launcher_local)
.setContentIntent(notificationPendingIntent) .setContentIntent(notificationPendingIntent)
.setAutoCancel(true) .setAutoCancel(true)
.setContentTitle(title) .setContentTitle(title)
@ -208,7 +208,6 @@ fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTP
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.header("Allow", "*/*") .header("Allow", "*/*")
.response { request, response, result -> .response { request, response, result ->
result.doAsyncResult { }
result.fold({ data -> result.fold({ data ->
val dataString = String(data) val dataString = String(data)
if (isJSONValid(dataString)) { if (isJSONValid(dataString)) {

@ -19,4 +19,5 @@
<string name="GEOFENCE_REQUEST_TOO_FREQUENT"> <string name="GEOFENCE_REQUEST_TOO_FREQUENT">
Geofence requests happened too frequently. Geofence requests happened too frequently.
</string> </string>
<string name="mapbox_access_token" translatable="false">sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg</string>
</resources> </resources>

@ -12,7 +12,23 @@ buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
maven { url 'https://developer.huawei.com/repo/' } 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 { // maven {
// url "https://dl.bintray.com/kotlin/kotlin-eap/" // 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.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath 'com.huawei.agconnect:agcp:1.5.2.300' classpath 'com.huawei.agconnect:agcp:1.5.2.300'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12' 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() google()
// jcenter() // jcenter()
mavenCentral() mavenCentral()
flatDir {
dirs 'libs'
}
maven { maven {
url 'https://developer.huawei.com/repo/' url 'https://developer.huawei.com/repo/'
} }
maven { maven {
url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" 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)
}
}
} }
} }

@ -21,19 +21,24 @@
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
} }
], ],
"services": { "services": {
"analytics_service": {
"status": 1
},
"appinvite_service": { "appinvite_service": {
"status": 1, "other_platform_oauth_client": [
"other_platform_oauth_client": [] {
}, "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"ads_service": { "client_type": 3
"status": 2 },
{
"client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.void.demo"
}
}
]
} }
} }
} }

@ -3,3 +3,6 @@ org.gradle.jvmargs=-Xmx4096m
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
android.suppressUnsupportedCompileSdk=33 android.suppressUnsupportedCompileSdk=33
MAPBOX_USER_NAME = "mapbox"
#MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
MAPBOX_DOWNLOADS_TOKEN="pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ"

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

@ -25,15 +25,20 @@
} }
], ],
"services": { "services": {
"analytics_service": {
"status": 1
},
"appinvite_service": { "appinvite_service": {
"status": 1, "other_platform_oauth_client": [
"other_platform_oauth_client": [] {
}, "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"ads_service": { "client_type": 3
"status": 2 },
{
"client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.void.demo"
}
}
]
} }
} }
} }

@ -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"
}

@ -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"
}

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>13.0</string>
</dict> </dict>
</plist> </plist>

@ -3,7 +3,7 @@ platform :ios, '14.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
# use_frameworks! :linkage => :static
project 'Runner', { project 'Runner', {
'Debug' => :debug, 'Debug' => :debug,
'Profile' => :release, 'Profile' => :release,
@ -33,6 +33,8 @@ target 'Runner' do
pod 'OpenTok', '~> 2.22.0' pod 'OpenTok', '~> 2.22.0'
pod 'VTO2Lib' pod 'VTO2Lib'
pod 'MapboxMaps', '10.18.2'
pod 'FLAnimatedImage'
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end end
@ -54,6 +56,7 @@ post_install do |installer|
] ]
build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'
build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' 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_path = build_configuration.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path) xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR") 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' if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle'
build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF' build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF'
end 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 end
end end

@ -8,17 +8,28 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 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 */; }; 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; };
301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; }; 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; };
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; };
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 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 */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; }; 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 */; }; 762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; };
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; }; 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; };
76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; }; 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 */; }; 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 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 */; }; E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; };
E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; }; E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; };
E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7623A25922BCE00FB5CCF /* FlutterConstants.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 */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = { 768D81742C6DF6E4005C655F /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */,
47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */,
47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */,
); );
name = "Embed Frameworks"; name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -58,12 +73,15 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = "<group>"; };
301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = "<group>"; }; 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = "<group>"; };
301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = "<group>"; }; 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = "<group>"; };
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = "<group>"; }; 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = "<group>"; };
306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = "<group>"; }; 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
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 = "<group>"; };
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = "<group>"; };
47C934FC2C91766400981BA7 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = "<group>"; };
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 = "<group>"; }; 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 = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -74,9 +92,15 @@
7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = "<group>"; }; 7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 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 = "<group>"; }; 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = "<group>"; };
76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = "<group>"; };
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = "<group>"; };
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = "<group>"; };
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = "<group>"; };
76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; 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 = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; }; 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 = "<group>"; };
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 = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 */, 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */,
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */, 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */,
E9620805255C2ED100D3A35D /* NetworkExtension.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; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -133,10 +160,13 @@
555EAAA626EFB641859EF0BE /* Frameworks */ = { 555EAAA626EFB641859EF0BE /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
47C934FC2C91766400981BA7 /* Penguin.xcframework */,
47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */,
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */,
76F2556027F1FFED0062C1CD /* PassKit.framework */, 76F2556027F1FFED0062C1CD /* PassKit.framework */,
76815B26275F381C00E66E94 /* HealthKit.framework */, 76815B26275F381C00E66E94 /* HealthKit.framework */,
E9620804255C2ED100D3A35D /* NetworkExtension.framework */, E9620804255C2ED100D3A35D /* NetworkExtension.framework */,
3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */, 8E413842321D0D624872E9BE /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -151,6 +181,18 @@
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
76D71B682C6B817500DAFB84 /* Penguin */ = {
isa = PBXGroup;
children = (
76D71B692C6B819000DAFB84 /* PenguinModel.swift */,
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */,
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */,
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */,
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */,
);
path = Penguin;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -186,6 +228,7 @@
97C146F01CF9000F007C117D /* Runner */ = { 97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
76D71B682C6B817500DAFB84 /* Penguin */,
762D738C274E42650063CE73 /* ring_30Sec.caf */, 762D738C274E42650063CE73 /* ring_30Sec.caf */,
762D738D274E42650063CE73 /* ring_30Sec.mp3 */, 762D738D274E42650063CE73 /* ring_30Sec.mp3 */,
306FE6C9271D8B54002D6EFC /* OpenTok */, 306FE6C9271D8B54002D6EFC /* OpenTok */,
@ -220,6 +263,7 @@
E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */,
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */, 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */,
E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */,
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */,
); );
path = Helper; path = Helper;
sourceTree = "<group>"; sourceTree = "<group>";
@ -254,7 +298,7 @@
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 768D81742C6DF6E4005C655F /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */, 487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */,
4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */, 4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */,
@ -274,7 +318,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1430; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
@ -419,12 +463,18 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */, 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */,
76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */,
E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */,
E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */,
76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */,
E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */,
E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */,
E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */,
E923EFD62587443800E3E751 /* HMGPlatformBridge.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 */, 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */,
E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */,
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */,
@ -528,6 +578,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -549,14 +600,17 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 4.5.95; MARKETING_VERSION = 4.5.991;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; 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 = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Profile; name = Profile;
@ -675,6 +729,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -696,14 +751,18 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 4.5.95; MARKETING_VERSION = 4.5.991;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile; SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Debug; name = Debug;
@ -713,6 +772,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -734,15 +794,18 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 4.5.95; MARKETING_VERSION = 4.5.991;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; 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 = singlefile;
"SWIFT_COMPILATION_MODE[arch=*]" = singlefile; "SWIFT_COMPILATION_MODE[arch=*]" = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Release; name = Release;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1430" LastUpgradeVersion = "1510"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

@ -30,11 +30,13 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
}else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
} }
} }

@ -0,0 +1,94 @@
import Foundation
import FLAnimatedImage
var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil
fileprivate var mainViewController:MainFlutterVC!
class HMGPenguinInPlatformBridge{
private let channelName = "launch_penguin_ui"
private static var shared_:HMGPenguinInPlatformBridge?
class func initialize(flutterViewController:MainFlutterVC){
shared_ = HMGPenguinInPlatformBridge()
mainViewController = flutterViewController
shared_?.openChannel()
}
func shared() -> 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)
}
}

@ -39,7 +39,7 @@
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>13.0</string>
<key>NFCReaderUsageDescription</key> <key>NFCReaderUsageDescription</key>
<string>This app requires NFC Usage access to allow for Online CheckIn for appointments.</string> <string>This app requires NFC Usage access to allow for Online CheckIn for appointments.</string>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
@ -60,7 +60,7 @@
<key>NSCalendarsUsageDescription</key> <key>NSCalendarsUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsWriteOnlyAccessUsageDescription</key> <key>NSCalendarsWriteOnlyAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsFullAccessUsageDescription</key> <key>NSCalendarsFullAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
@ -120,5 +120,7 @@
<true/> <true/>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>MBXAccessToken</key>
<string>pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ</string>
</dict> </dict>
</plist> </plist>

@ -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
}
}

@ -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)
}
}
}
}

@ -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")
// }
//}

@ -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)")
}
}

@ -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()
}
}

@ -22,8 +22,8 @@ var PACKAGES_ORDER_HISTORY = '/api/orders/items';
var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara';
// var BASE_URL = 'http://10.50.100.198:2018/'; // var BASE_URL = 'http://10.50.100.198:2018/';
// var BASE_URL = 'http://10.50.100.198:4422/'; // var BASE_URL = 'http://10.50.100.198:4422/';
var BASE_URL = 'https://uat.hmgwebservices.com/'; // var BASE_URL = 'https://uat.hmgwebservices.com/';
// var BASE_URL = 'https://hmgwebservices.com/'; var BASE_URL = 'https://hmgwebservices.com/';
// var BASE_URL = 'http://10.20.200.111:1010/'; // var BASE_URL = 'http://10.20.200.111:1010/';
// var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; // var BASE_URL = 'https://orash.cloudsolutions.com.sa/';
// var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/';
@ -215,6 +215,7 @@ var GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID';
//URL to get clinic list //URL to get clinic list
var GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; 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 //URL to get active appointment list
var GET_ACTIVE_APPOINTMENTS_LIST_URL = "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; var GET_ACTIVE_APPOINTMENTS_LIST_URL = "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber";
@ -313,6 +314,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_FEES = 'Services/DoctorApplication.svc/REST/GetERAppointmentFees';
var GET_ER_APPOINTMENT_TIME = 'Services/ER_VirtualCall.svc/REST/GetRestTime'; 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 ADD_NEW_CALL_FOR_PATIENT_ER = 'Services/DoctorApplication.svc/REST/NewCallForPatientER';
var GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; var GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory';
@ -333,18 +336,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 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 HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation';
var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory'; var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory';
var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert'; var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert';
var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update'; 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 //URL to get medicine and pharmacies list
var CHANNEL = 3; var CHANNEL = 3;
var GENERAL_ID = 'Cs2020@2016\$2958'; var GENERAL_ID = 'Cs2020@2016\$2958';
var IP_ADDRESS = '10.20.10.20'; var IP_ADDRESS = '10.20.10.20';
var VERSION_ID = 16.0; var VERSION_ID = 16.7;
var SETUP_ID = '91877'; var SETUP_ID = '91877';
var LANGUAGE = 2; var LANGUAGE = 2;
// var PATIENT_OUT_SA = 0; // var PATIENT_OUT_SA = 0;
@ -647,6 +657,8 @@ var GET_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/getBirthNotification_bymoth
var SAVE_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/SaveBirthNotification'; var SAVE_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/SaveBirthNotification';
var INSERT_GENERAL_ADMISSION_CONSENT = 'Services/INPs.svc/REST/Inp_insertAAForGeneralAdmissionConsent';
//Meal Plan APIs //Meal Plan APIs
var GET_ADMITTED_PATIENTS = 'Services/MOP.svc/REST/GetAdmittedPatients'; var GET_ADMITTED_PATIENTS = 'Services/MOP.svc/REST/GetAdmittedPatients';
var GET_CURRENT_WEEKID_WEEKDAY = 'Services/MOP.svc/REST/GetCurrentWeekAndDayHMGMP'; var GET_CURRENT_WEEKID_WEEKDAY = 'Services/MOP.svc/REST/GetCurrentWeekAndDayHMGMP';
@ -665,6 +677,23 @@ var GET_WE_CARE_TOUR_URL = 'Services/Consent.svc/Rest/Consent_VirtualJurny_Url_G
var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification'; 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_ADVANCE_BALANCE = 'Services/OUTPs.svc/Rest/getPatientAdvanceBalanceAmountByClinic';
var GET_PROJECT_FROM_NFC = 'Services/OUTPs.svc/Rest/GetProjectByNFC';
//PAYFORT //PAYFORT
var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails"; var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails";
var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse"; var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse";

@ -45,6 +45,8 @@ const Map localizedValues = {
'name': {'en': 'Name', 'ar': 'الإسم'}, 'name': {'en': 'Name', 'ar': 'الإسم'},
'doctor': {'en': 'Doctor', 'ar': 'الطبيب'}, 'doctor': {'en': 'Doctor', 'ar': 'الطبيب'},
'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'},
'hospitalName': {'en': 'Hospital Name', 'ar': 'اسم المستشفى'},
'NoClinicFound': {'en': 'No Clinic Found', 'ar': 'لم يتم العثور على عيادة'},
'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'},
'nearestAppo': {'en': 'Nearest Appointment', 'ar': 'أقرب موعد'}, 'nearestAppo': {'en': 'Nearest Appointment', 'ar': 'أقرب موعد'},
'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'},
@ -1870,8 +1872,14 @@ const Map localizedValues = {
"insuranceClassName": {"en": "Insurance Class", "ar": "فئة التأمين"}, "insuranceClassName": {"en": "Insurance Class", "ar": "فئة التأمين"},
"insuranceRequestSubmit": {"en": "Your insurance update request has been submitted successfully.", "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. يرجى زيارة مكتب الاستقبال لتسجيل الوصول"}, "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": "رجاء إدخال مكان العمل:"}, "enter-workplace-name": {"en": "Please enter your workplace details:", "ar": "الرجاء إدخال تفاصيل مكان عملك:"},
"workplaceName": {"en": "Workplace name:", "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": "اتصل بدعم اللايف كير"}, "callLiveCareSupport": {"en": "Call LiveCare Support", "ar": "اتصل بدعم اللايف كير"},
"needApproval": { "needApproval": {
"en": "Your sick leave is under process in medical administration, you will be notified once approved.", "en": "Your sick leave is under process in medical administration, you will be notified once approved.",
@ -1943,12 +1951,25 @@ const Map localizedValues = {
"generalInstructions": {"en": "General Instructions:", "ar": "تعليمات عامة:"}, "generalInstructions": {"en": "General Instructions:", "ar": "تعليمات عامة:"},
"copyLink": {"en": "COPY LINK", "ar": "نسخ الوصلة:"}, "copyLink": {"en": "COPY LINK", "ar": "نسخ الوصلة:"},
"paymentLinkCopied": {"en": "Payment link copied to your clipboard!'", "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": "أو يمكنك نسخ رابط الدفع من الأسفل وإرساله إلى شخص يمكنه الدفع نيابة عنك:"}, "copyLinkTxt": {
"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 <insert number here>", "ar": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>"}, "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 <insert number here>",
"ar": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>"
},
"admissionNo": {"en": "Admission No", "ar": "رقم القبول:"}, "admissionNo": {"en": "Admission No", "ar": "رقم القبول:"},
"admissionReqNo": {"en": "Admission Request No", "ar": "رقم طلب القبول:"}, "admissionReqNo": {"en": "Admission Request No", "ar": "رقم طلب القبول:"},
"dischargeDate": {"en": "Discharge Date", "ar": "تاريخ التفريغ"}, "dischargeDate": {"en": "Discharge Date", "ar": "تاريخ التفريغ"},
"selectAdmissionText": {"en": "Please select one of the admissions from below to view medical reports:", "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": { "invalidEligibility": {
"en": "You cannot make online payment because you are not eligible to use the provided service.", "en": "You cannot make online payment because you are not eligible to use the provided service.",
"ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة." "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة."
@ -1965,10 +1986,7 @@ const Map localizedValues = {
"validInsurance": {"en": "Do you have a valid insurance?", "ar": "هل لديك تأمين صالح؟"}, "validInsurance": {"en": "Do you have a valid insurance?", "ar": "هل لديك تأمين صالح؟"},
"contactRRT": {"en": "Contact RRT", "ar": "تواصل مع فريق الاستجابة السريعة"}, "contactRRT": {"en": "Contact RRT", "ar": "تواصل مع فريق الاستجابة السريعة"},
"checkInViaLocation": {"en": "Check-In Via Location", "ar": "تسجيل الوصول عبر الموقع"}, "checkInViaLocation": {"en": "Check-In Via Location", "ar": "تسجيل الوصول عبر الموقع"},
"locationCheckInError": { "locationCheckInError": {"en": "Please ensure you're within the hospital location to perform online check-in.", "ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت."},
"en": "Please make sure that you're within the hospital location to perform online check-in.",
"ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت."
},
"upcoming": {"en": "Upcoming", "ar": "المواعيد القادمة"}, "upcoming": {"en": "Upcoming", "ar": "المواعيد القادمة"},
"noUpcomingAppointment": {"en": "No upcoming appointments", "ar": "لا توجد مواعيد القادمة"}, "noUpcomingAppointment": {"en": "No upcoming appointments", "ar": "لا توجد مواعيد القادمة"},
"locationTimeoutError": {"en": "Unable to fetch your location, Please try again.", "ar": "غير قادر على جلب موقعك، يرجى المحاولة مرة أخرى."}, "locationTimeoutError": {"en": "Unable to fetch your location, Please try again.", "ar": "غير قادر على جلب موقعك، يرجى المحاولة مرة أخرى."},
@ -1976,6 +1994,26 @@ const Map localizedValues = {
"selectHospitalBloodDonation": {"en": "Please select the hospital you want to book an appointment with: ", "ar": "يرجى اختيار المستشفى الذي تريد حجز موعد معه:"}, "selectHospitalBloodDonation": {"en": "Please select the hospital you want to book an appointment with: ", "ar": "يرجى اختيار المستشفى الذي تريد حجز موعد معه:"},
"wecare": {"en": "We Care", "ar": "نحن نهتم"}, "wecare": {"en": "We Care", "ar": "نحن نهتم"},
"myinstructions": {"en": "My Instructions", "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 doctors 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": "بحث العيادة"}, "searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"},
"enterMobileNumber": {"en": "Enter Mobile Number", "ar": "أدخل رقم الجوال"}, "enterMobileNumber": {"en": "Enter Mobile Number", "ar": "أدخل رقم الجوال"},
"videoCall": {"en": "Video Call", "ar": "اتصال فيديو"}, "videoCall": {"en": "Video Call", "ar": "اتصال فيديو"},
@ -1983,4 +2021,103 @@ const Map localizedValues = {
"phoneCall": {"en": "Phone Call", "ar": "اتصال هاتفية"}, "phoneCall": {"en": "Phone Call", "ar": "اتصال هاتفية"},
"selectCallType": {"en": "Select Call Type", "ar": "حدد نوع المكالمة"}, "selectCallType": {"en": "Select Call Type", "ar": "حدد نوع المكالمة"},
"selectedCallType": {"en": "Selected Call Type", "ar": "نوع المكالمة المحدد"}, "selectedCallType": {"en": "Selected Call Type", "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":
"لقد قرأت وفهمت وأوافق على الشروط والأحكام المبينة أعلاه وأوافق على الإلتزام بالمتطلبات المذكورة تجاه المستشفى ، لقد قرأت التفاصيل المبينة في نموذج التسجيل الخاص بي وأقر بأنها صحيحة. أنا الموقع ادناه أقر بأنه أتيحت لي الفرصة لطرح الأسئلة والتحفظات بشأن هذه الموافقة، وتلقيت إجابات مرضية على جميع إستفساراتي."
},
}; };

@ -31,8 +31,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
/// onFailure: (String error, int statusCode) {}, /// onFailure: (String error, int statusCode) {},
/// body: Map(); /// body: Map();
/// ///
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
locator<AuthenticatedUserObject>();
VitalSignService _vitalSignService = locator<VitalSignService>(); VitalSignService _vitalSignService = locator<VitalSignService>();
class BaseAppClient { class BaseAppClient {
@ -40,12 +39,12 @@ class BaseAppClient {
post(String endPoint, post(String endPoint,
{required Map<String, dynamic> body, {required Map<String, dynamic> body,
required Function(dynamic response, int statusCode) onSuccess, required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
bool isAllowAny = false, bool isAllowAny = false,
bool isExternal = false, bool isExternal = false,
bool isRCService = false, bool isRCService = false,
bool bypassConnectionCheck = false}) async { bool bypassConnectionCheck = false}) async {
String url; String url;
if (isExternal) { if (isExternal) {
url = endPoint; url = endPoint;
@ -56,25 +55,20 @@ class BaseAppClient {
url = BASE_URL + endPoint; url = BASE_URL + endPoint;
} }
try { try {
String? pharmacyToken = String? pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
Map<String, String> headers = { Map<String, String> headers = {'Content-Type': 'application/json', 'Accept': 'application/json'};
'Content-Type': 'application/json',
'Accept': 'application/json'
};
if (!isExternal) { if (!isExternal) {
String? token = await sharedPref.getString(TOKEN); String? token = await sharedPref.getString(TOKEN);
String? languageID = String? languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
if (endPoint == SEND_ACTIVATION_CODE) { if (endPoint == SEND_ACTIVATION_CODE) {
languageID = 'en'; languageID = 'en';
} }
if (body.containsKey('SetupID')) { if (body.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID') body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null ? body['SetupID'] != null
? body['SetupID'] ? body['SetupID']
: SETUP_ID : SETUP_ID
: SETUP_ID; : SETUP_ID;
} }
@ -87,8 +81,8 @@ class BaseAppClient {
body['LanguageID'] = body['LanguageID'] == 'ar' body['LanguageID'] = body['LanguageID'] == 'ar'
? 1 ? 1
: body['LanguageID'] == 'en' : body['LanguageID'] == 'en'
? 2 ? 2
: body['LanguageID']; : body['LanguageID'];
} else { } else {
body['LanguageID'] = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isArabic ? 1 : 2; body['LanguageID'] = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isArabic ? 1 : 2;
} }
@ -120,16 +114,16 @@ class BaseAppClient {
if (body.containsKey('isDentalAllowedBackend')) { if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null ? body['isDentalAllowedBackend'] != null
? body['isDentalAllowedBackend'] ? body['isDentalAllowedBackend']
: IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND; : IS_DENTAL_ALLOWED_BACKEND;
} }
body['DeviceTypeID'] = Platform.isIOS body['DeviceTypeID'] = Platform.isIOS
? 1 ? 1
: await Utils.isGoogleServicesAvailable() : await Utils.isGoogleServicesAvailable()
? 2 ? 2
: 3; : 3;
if (!body.containsKey('IsPublicRequest')) { if (!body.containsKey('IsPublicRequest')) {
// if (!body.containsKey('PatientType')) { // if (!body.containsKey('PatientType')) {
@ -166,17 +160,14 @@ class BaseAppClient {
if (user != null) { if (user != null) {
body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token; body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token;
body['PatientID'] = body['PatientID'] != null body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
? body['PatientID']
: user['PatientID'];
body['PatientOutSA'] = body.containsKey('PatientOutSA') body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null ? body['PatientOutSA'] != null
? body['PatientOutSA'] ? body['PatientOutSA']
: user['OutSA'] : user['OutSA']
: user['OutSA']; : user['OutSA'];
body['SessionID'] = getSessionId( body['SessionID'] = getSessionId(body['TokenID'] != null ? body['TokenID'] : ""); //getSe
body['TokenID'] != null ? body['TokenID'] : ""); //getSe
// body['SessionID'] = body['TokenID']; //getSe // body['SessionID'] = body['TokenID']; //getSe
// headers = { // headers = {
@ -193,7 +184,7 @@ class BaseAppClient {
// body['IdentificationNo'] = 1023854217; // body['IdentificationNo'] = 1023854217;
// body['MobileNo'] = "531940021"; //0560717232 // body['MobileNo'] = "531940021"; //0560717232
// body['PatientID'] = 283093; //4609100 // body['PatientID'] = 4768303; //4609100
// body['TokenID'] = "@dm!n"; // body['TokenID'] = "@dm!n";
// Patient ID: 3027574 // Patient ID: 3027574
@ -202,21 +193,23 @@ class BaseAppClient {
body.removeWhere((key, value) => key == null || value == null); 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) { // if (AppGlobal.isNetworkDebugEnabled) {
print("URL : $url"); print("URL : $url");
final jsonBody = json.encode(body); final jsonBody = json.encode(body);
print(jsonBody); print(jsonBody);
// } // }
if (await Utils.checkConnection( if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) {
bypassConnectionCheck: bypassConnectionCheck)) { 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; final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode); onFailure('Error While Fetching data', statusCode);
logApiEndpointError( logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
endPoint, 'Error While Fetching data', statusCode);
} else { } else {
// var decoded = utf8.decode(response.bodyBytes); // var decoded = utf8.decode(response.bodyBytes);
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -230,12 +223,8 @@ class BaseAppClient {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
if (parsed['ErrorType'] == 2) { if (parsed['ErrorType'] == 2) {
await logout(); await logout();
@ -254,46 +243,28 @@ class BaseAppClient {
// if (parsed != null) { // if (parsed != null) {
// onSuccess(parsed, statusCode); // onSuccess(parsed, statusCode);
// } else { // } else {
onFailure( onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
// logout(); // logout();
// } // }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) { if (parsed['SameClinicApptList'] != null) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['message'] == null && if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", onFailure("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure(parsed['ErrorSearchMsg'], statusCode); onFailure(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
endPoint, parsed['ErrorSearchMsg'], statusCode);
} }
} else { } else {
onFailure( onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} }
} }
} }
@ -305,18 +276,11 @@ class BaseAppClient {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure( onFailure(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} else { } else {
onFailure( onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -325,23 +289,17 @@ class BaseAppClient {
} }
} else { } else {
onFailure('Please Check The Internet Connection', -1); onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
onFailure(e.toString(), -1); onFailure(e.toString(), -1);
_analytics.errorTracking _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url");
.log(endPoint, error: "api exception: $e - API Path: $url");
} }
} }
postPharmacy(String endPoint, postPharmacy(String endPoint,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
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 token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
String url; String url;
@ -358,16 +316,13 @@ class BaseAppClient {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': pharmacyToken ?? '', 'Authorization': pharmacyToken ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
}; };
if (!isExternal) { if (!isExternal) {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
// if (body.containsKey('SetupID')) { // if (body.containsKey('SetupID')) {
// body['SetupID'] = body.containsKey('SetupID') // body['SetupID'] = body.containsKey('SetupID')
@ -429,14 +384,12 @@ class BaseAppClient {
print("Headers : ${json.encode(headers)}"); print("Headers : ${json.encode(headers)}");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http.post(Uri.parse(url.trim()), final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
body: json.encode(body), headers: headers);
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
logApiEndpointError( logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
endPoint, 'Error While Fetching data', statusCode);
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -444,12 +397,8 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
if (isAllowAny) { if (isAllowAny) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
@ -464,56 +413,29 @@ class BaseAppClient {
if (parsed != null) { if (parsed != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode); logApiEndpointError(endPoint, 'session logged out', statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint, 'session logged out', statusCode);
logout(); logout();
} }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) { if (parsed['SameClinicApptList'] != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] == null && if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure!("Server Error found with no available message", onFailure!("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure!(parsed['ErrorSearchMsg'], statusCode); onFailure!(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
endPoint,
parsed['ErrorSearchMsg'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} else { } else {
onFailure!( onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} }
} else if (!parsed['IsAuthenticated']) { } else if (!parsed['IsAuthenticated']) {
@ -525,22 +447,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure!( onFailure!(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -548,8 +459,7 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
@ -560,18 +470,18 @@ class BaseAppClient {
Future navigateToAppUpdate(context, String text) async { Future navigateToAppUpdate(context, String text) async {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
locator<NavigationService>().navigatorKey.currentContext!, locator<NavigationService>().navigatorKey.currentContext!,
MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)), MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)),
(Route<dynamic> route) => false, (Route<dynamic> route) => false,
); );
} }
get(String endPoint, get(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess, {required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams, Map<String, dynamic>? queryParams,
bool isExternal = false, bool isExternal = false,
bool isRCService = false}) async { bool isRCService = false}) async {
String url; String url;
if (isExternal) { if (isExternal) {
url = endPoint; url = endPoint;
@ -592,10 +502,7 @@ class BaseAppClient {
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http.get( final response = await http.get(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: { headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
'Content-Type': 'application/json',
'Accept': 'application/json'
},
); );
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
@ -609,17 +516,16 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
getPharmacy(String endPoint, getPharmacy(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess, {required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
bool isAllowAny = false, bool isAllowAny = false,
bool isExternal = false, bool isExternal = false,
Map<String, dynamic>? queryParams}) async { Map<String, dynamic>? queryParams}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
@ -642,9 +548,7 @@ class BaseAppClient {
'Content-Type': 'text/html; charset=utf-8', 'Content-Type': 'text/html; charset=utf-8',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': token ?? '', 'Authorization': token ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
// 'Host': "mdlaboratories.com", // 'Host': "mdlaboratories.com",
@ -654,19 +558,14 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
if (statusCode == 401) { if (statusCode == 401) {
onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
statusCode); logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
logApiEndpointError(
endPoint,
TranslationBase.of(AppGlobal.context).pharmacyRelogin,
statusCode);
Navigator.of(AppGlobal.context).pushNamed(HOME); Navigator.of(AppGlobal.context).pushNamed(HOME);
} else { } else {
var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); var bodyUtf = json.decode(utf8.decode(response.bodyBytes));
// print(bodyUtf); // print(bodyUtf);
onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode); onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
} }
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
@ -675,25 +574,23 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simplePost( simplePost(
String fullUrl, { String fullUrl, {
required Map<dynamic, dynamic> body, required Map<dynamic, dynamic> body,
required Map<String, String> headers, required Map<String, String> headers,
required Function(dynamic response, int statusCode) onSuccess, required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
}) async { }) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
// print("body: $body"); // print("body: $body");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.post( final response = await http.post(
Uri.parse(url.trim()), Uri.parse(url.trim()),
body: json.encode(body), body: json.encode(body),
@ -701,12 +598,7 @@ class BaseAppClient {
); );
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
simplePost(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
body: body,
headers: headers);
// print(response.body.toString()); // print(response.body.toString());
@ -718,16 +610,12 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simpleGet(String fullUrl, simpleGet(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess, {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map<String, dynamic>? queryParams, Map<String, String>? headers}) async {
Function(String error, int statusCode)? onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? headers}) async {
headers = headers ?? {}; headers = headers ?? {};
String url = fullUrl; String url = fullUrl;
@ -739,8 +627,7 @@ class BaseAppClient {
} }
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers.addAll( headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.get( final response = await http.get(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: headers, headers: headers,
@ -748,12 +635,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams);
simpleGet(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
headers: headers,
queryParams: queryParams);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -763,22 +645,17 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simplePut(String fullUrl, simplePut(String fullUrl,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Map<String, String>? headers, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async {
Map<String, String>? headers,
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure}) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.put( final response = await http.put(
Uri.parse(url.trim()), Uri.parse(url.trim()),
body: json.encode(body), body: json.encode(body),
@ -787,12 +664,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body);
simplePut(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
headers: headers,
body: body);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -802,16 +674,12 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simpleDelete(String fullUrl, simpleDelete(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess, {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map<String, String>? queryParams, Map<String, String>? headers}) async {
Function(String error, int statusCode)? onFailure,
Map<String, String>? queryParams,
Map<String, String>? headers}) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
@ -823,8 +691,7 @@ class BaseAppClient {
} }
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.delete( final response = await http.delete(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: headers, headers: headers,
@ -832,12 +699,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers);
simpleDelete(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
queryParams: queryParams,
headers: headers);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -847,13 +709,11 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
Future<bool> handleUnauthorized(int statusCode, Future<bool> handleUnauthorized(int statusCode, {required String forUrl}) async {
{required String forUrl}) async {
if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) {
final token = await generatePackagesToken(); final token = await generatePackagesToken();
packagesAuthHeader['Authorization'] = 'Bearer $token'; packagesAuthHeader['Authorization'] = 'Bearer $token';
@ -866,10 +726,8 @@ class BaseAppClient {
await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(LOGIN_TOKEN_ID);
await sharedPref.remove(PHARMACY_CUSTOMER_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID);
await authenticatedUserObject.getUser(); await authenticatedUserObject.getUser();
Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isLogin = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isLogin = false;
false; var model = Provider.of<ToDoCountProviderModel>(AppGlobal.context, listen: false);
var model =
Provider.of<ToDoCountProviderModel>(AppGlobal.context, listen: false);
_vitalSignService.weightKg = ""; _vitalSignService.weightKg = "";
_vitalSignService.heightCm = ""; _vitalSignService.heightCm = "";
model.setState(0, 0, false, null); model.setState(0, 0, false, null);
@ -884,8 +742,7 @@ class BaseAppClient {
static defaultHttpParameters() async { static defaultHttpParameters() async {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
var params = {}; var params = {};
if (user != null) { if (user != null) {
@ -905,11 +762,7 @@ class BaseAppClient {
} }
pharmacyPost(String endPoint, pharmacyPost(String endPoint,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
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 token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
String url; String url;
@ -921,14 +774,13 @@ class BaseAppClient {
try { try {
if (isExternal) { if (isExternal) {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
if (body!.containsKey('SetupID')) { if (body!.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID') body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null ? body['SetupID'] != null
? body['SetupID'] ? body['SetupID']
: SETUP_ID : SETUP_ID
: SETUP_ID; : SETUP_ID;
} }
@ -940,15 +792,15 @@ class BaseAppClient {
body['generalid'] = GENERAL_ID; body['generalid'] = GENERAL_ID;
body['PatientOutSA'] = body.containsKey('PatientOutSA') body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null ? body['PatientOutSA'] != null
? body['PatientOutSA'] ? body['PatientOutSA']
: user['OutSA'] : user['OutSA']
: user['OutSA']; : user['OutSA'];
if (body.containsKey('isDentalAllowedBackend')) { if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null ? body['isDentalAllowedBackend'] != null
? body['isDentalAllowedBackend'] ? body['isDentalAllowedBackend']
: IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND; : IS_DENTAL_ALLOWED_BACKEND;
} }
@ -957,24 +809,22 @@ class BaseAppClient {
if (!body.containsKey('IsPublicRequest')) { if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType') body['PatientType'] = body.containsKey('PatientType')
? body['PatientType'] != null ? body['PatientType'] != null
? body['PatientType'] ? body['PatientType']
: user['PatientType'] != null : user['PatientType'] != null
? user['PatientType'] ? user['PatientType']
: user['PatientType'] : user['PatientType']
: user['PatientType']; : user['PatientType'];
body['PatientTypeID'] = body.containsKey('PatientTypeID') body['PatientTypeID'] = body.containsKey('PatientTypeID')
? body['PatientTypeID'] != null ? body['PatientTypeID'] != null
? body['PatientTypeID'] ? body['PatientTypeID']
: user['PatientType'] != null : user['PatientType'] != null
? user['PatientType'] ? user['PatientType']
: user['PatientType'] : user['PatientType']
: user['PatientType']; : user['PatientType'];
if (user != null) { if (user != null) {
body['TokenID'] = token; body['TokenID'] = token;
body['PatientID'] = body['PatientID'] != null body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
? body['PatientID']
: user['PatientID'];
body['PatientOutSA'] = user['OutSA']; body['PatientOutSA'] = user['OutSA'];
// body['SessionID'] = SESSION_ID; //getSessionId(token); // body['SessionID'] = SESSION_ID; //getSessionId(token);
} }
@ -986,14 +836,11 @@ class BaseAppClient {
var ss = json.encode(body); var ss = json.encode(body);
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: {
.post(Uri.parse(url.trim()), body: json.encode(body), headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': token ?? '', 'Authorization': token ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
}); });
@ -1001,15 +848,8 @@ class BaseAppClient {
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
onFailure!( onFailure!(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
parsed['error']['ErrorEndUserMsgN'] ?? logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
'Error While Fetching data',
statusCode);
logApiEndpointError(
endPoint,
parsed['error']['ErrorEndUserMsgN'] ??
'Error While Fetching data',
statusCode);
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -1017,8 +857,7 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']);
} }
if (isAllowAny) { if (isAllowAny) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
@ -1033,47 +872,25 @@ class BaseAppClient {
if (parsed != null) { if (parsed != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
logout(); logout();
} }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['message'] == null &&
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure!("Server Error found with no available message", onFailure!("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure!(parsed['ErrorSearchMsg'], statusCode); onFailure!(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
endPoint, parsed['ErrorSearchMsg'], statusCode);
} }
} else { } else {
onFailure!( onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} else if (!parsed['IsAuthenticated']) { } else if (!parsed['IsAuthenticated']) {
await logout(); await logout();
@ -1084,18 +901,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure!( onFailure!(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -1103,8 +913,7 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
@ -1116,15 +925,11 @@ class BaseAppClient {
Future<String> generatePackagesToken() async { Future<String> generatePackagesToken() async {
var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN; var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN;
var body = { var body = {
"api_client": { "api_client": {"client_id": "a4ab6be4-424f-4836-b032-46caed88e184", "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"}
"client_id": "a4ab6be4-424f-4836-b032-46caed88e184",
"client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"
}
}; };
String? token; String? token;
final completer = Completer(); final completer = Completer();
simplePost(url, body: body, headers: {}, simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) {
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) { if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
token = jsonResponse['auth_token']; token = jsonResponse['auth_token'];

@ -124,12 +124,15 @@ class LabsService extends BaseService {
return Future.value(localRes); 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; hasError = false;
Map<String, dynamic> body = Map(); Map<String, dynamic> body = Map();
body['Placeofwork'] = workplaceName; body['Placeofwork'] = workplaceName;
body['Placeofworkar'] = workplaceNameAR; body['PlaceofworkAr'] = workplaceNameAR;
body['Occupation'] = occupation;
body['OccupationAr'] = occupationAR;
body['Req_ID'] = requestNumber; body['Req_ID'] = requestNumber;
body['TargetSetupID'] = setupID; body['TargetSetupID'] = setupID;
body['ProjectID'] = projectID; body['ProjectID'] = projectID;

@ -72,11 +72,15 @@ class MedicalService extends BaseService {
dynamic localRes; dynamic localRes;
await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, onSuccess: (response, statusCode) async { await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, onSuccess: (response, statusCode) async {
localRes = response; localRes = response;
freeSlots.clear();
localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item));
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
throw error; hasError = true;
super.error = error;
// throw error;
}, body: request); }, body: request);
freeSlots.clear(); // freeSlots.clear();
localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); // localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item));
// localRes['List_DoctorWorkingHoursTable'].forEach((item) => // localRes['List_DoctorWorkingHoursTable'].forEach((item) =>
// {doctorScheduleResponse.add(DoctorScheduleResponse.fromJson(item))}); // {doctorScheduleResponse.add(DoctorScheduleResponse.fromJson(item))});
} }

@ -18,7 +18,10 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
import '../../models/Appointments/DoctorListResponse.dart';
bool isAppArabic = false; bool isAppArabic = false;
class ProjectViewModel extends BaseViewModel { class ProjectViewModel extends BaseViewModel {
GAnalytics get analytics => locator<GAnalytics>(); GAnalytics get analytics => locator<GAnalytics>();
@ -38,6 +41,7 @@ class ProjectViewModel extends BaseViewModel {
dynamic searchvalue; dynamic searchvalue;
bool isLogin = false; bool isLogin = false;
bool _isAllAppointmentsLoaded = false; bool _isAllAppointmentsLoaded = false;
bool get isAllAppointmentsLoaded => _isAllAppointmentsLoaded; bool get isAllAppointmentsLoaded => _isAllAppointmentsLoaded;
bool isPatientAdmitted = false; bool isPatientAdmitted = false;
bool patientHasAdmissionRequest = false; bool patientHasAdmissionRequest = false;
@ -45,15 +49,36 @@ class ProjectViewModel extends BaseViewModel {
GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel(); GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel();
GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel(); 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) { void setIsAllAppointmentsLoaded(bool value) {
_isAllAppointmentsLoaded = value; _isAllAppointmentsLoaded = value;
notifyListeners(); notifyListeners();
} }
RegisterInfoResponse _registerInfo = RegisterInfoResponse(); RegisterInfoResponse _registerInfo = RegisterInfoResponse();
RegisterInfoResponse get registerInfo => _registerInfo; RegisterInfoResponse get registerInfo => _registerInfo;
dynamic get searchValue => searchvalue; dynamic get searchValue => searchvalue;
Locale get appLocal => _appLocale; Locale get appLocal => _appLocale;
@ -70,7 +95,9 @@ class ProjectViewModel extends BaseViewModel {
List<ProjectDetailListModel> _projectDetailListModel = []; List<ProjectDetailListModel> _projectDetailListModel = [];
List<PrivilegeModel> get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser; List<PrivilegeModel> get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser;
List<VidaPlusProjectListModel> get vidaPlusProjectList => _vidaPlusProjectListModel; List<VidaPlusProjectListModel> get vidaPlusProjectList => _vidaPlusProjectListModel;
List<HMCProjectListModel> get hMCProjectListModel => _hMCProjectListModel; List<HMCProjectListModel> get hMCProjectListModel => _hMCProjectListModel;
List<ProjectDetailListModel> get projectDetailListModel => _projectDetailListModel; List<ProjectDetailListModel> get projectDetailListModel => _projectDetailListModel;
@ -137,6 +164,11 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners(); notifyListeners();
} }
setIsIndoorNavigationEnabled(bool isEnabled) {
this.isIndoorNavigationEnabled = isEnabled;
notifyListeners();
}
setPatientHasAdmissionRequest(bool hasAdmissionRequest) { setPatientHasAdmissionRequest(bool hasAdmissionRequest) {
this.patientHasAdmissionRequest = hasAdmissionRequest; this.patientHasAdmissionRequest = hasAdmissionRequest;
notifyListeners(); notifyListeners();
@ -200,8 +232,6 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners(); notifyListeners();
} }
bool havePrivilege(int id) { bool havePrivilege(int id) {
bool isHavePrivilege = false; bool isHavePrivilege = false;
try { try {
@ -222,7 +252,7 @@ class ProjectViewModel extends BaseViewModel {
@override @override
void dispose() { void dispose() {
if (subscription != null) subscription.cancel(); if (subscription != null) subscription.cancel();
super.dispose(); super.dispose();
} }

@ -44,6 +44,8 @@ class DoctorList {
List<String>? specialityN; List<String>? specialityN;
dynamic workingHours; dynamic workingHours;
dynamic decimalDoctorRate; dynamic decimalDoctorRate;
String? projectBottomName;
String? projectTopName;
DoctorList( DoctorList(
{this.clinicID, {this.clinicID,
@ -90,7 +92,9 @@ class DoctorList {
this.speciality, this.speciality,
this.specialityN, this.specialityN,
this.workingHours, this.workingHours,
this.decimalDoctorRate}); this.decimalDoctorRate,
this.projectBottomName,
this.projectTopName});
DoctorList.fromJson(Map<String, dynamic> json) { DoctorList.fromJson(Map<String, dynamic> json) {
clinicID = json['ClinicID']; clinicID = json['ClinicID'];
@ -138,6 +142,8 @@ class DoctorList {
if (json.containsKey('SpecialityN') && json['SpecialityN'] != null) specialityN = json['SpecialityN'].cast<String>(); if (json.containsKey('SpecialityN') && json['SpecialityN'] != null) specialityN = json['SpecialityN'].cast<String>();
workingHours = json['WorkingHours']; workingHours = json['WorkingHours'];
decimalDoctorRate = json['DecimalDoctorRate']; decimalDoctorRate = json['DecimalDoctorRate'];
projectBottomName = json['ProjectNameBottom'];
projectTopName = json['ProjectNameTop'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -188,6 +194,10 @@ class DoctorList {
data['DecimalDoctorRate'] = this.decimalDoctorRate; data['DecimalDoctorRate'] = this.decimalDoctorRate;
return data; return data;
} }
String getProjectCompleteName(){
return "${this.projectTopName} ${this.projectBottomName}";
}
} }
class PatientDoctorAppointmentList { class PatientDoctorAppointmentList {

@ -0,0 +1,59 @@
class PatientPackageComponent {
List<PatientPackageComponents>? patientPackageComponents;
PatientPackageComponent({this.patientPackageComponents});
PatientPackageComponent.fromJson(Map<String, dynamic> json) {
if (json['PatientPackageComponents'] != null) {
patientPackageComponents = <PatientPackageComponents>[];
json['PatientPackageComponents'].forEach((v) {
patientPackageComponents!.add(new PatientPackageComponents.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

@ -0,0 +1,96 @@
class EROnlineCheckInPaymentDetailsResponse {
num? cashPrice;
num? cashPriceTax;
num? cashPriceWithTax;
int? companyId;
String? companyName;
num? companyShareWithTax;
dynamic errCode;
int? groupID;
String? insurancePolicyNo;
String? message;
String? patientCardID;
num? patientShare;
num? patientShareWithTax;
num? patientTaxAmount;
int? policyId;
String? policyName;
String? procedureId;
String? procedureName;
dynamic setupID;
int? statusCode;
String? subPolicyNo;
EROnlineCheckInPaymentDetailsResponse(
{this.cashPrice,
this.cashPriceTax,
this.cashPriceWithTax,
this.companyId,
this.companyName,
this.companyShareWithTax,
this.errCode,
this.groupID,
this.insurancePolicyNo,
this.message,
this.patientCardID,
this.patientShare,
this.patientShareWithTax,
this.patientTaxAmount,
this.policyId,
this.policyName,
this.procedureId,
this.procedureName,
this.setupID,
this.statusCode,
this.subPolicyNo});
EROnlineCheckInPaymentDetailsResponse.fromJson(Map<String, dynamic> json) {
cashPrice = json['CashPrice'];
cashPriceTax = json['CashPriceTax'];
cashPriceWithTax = json['CashPriceWithTax'];
companyId = json['CompanyId'];
companyName = json['CompanyName'];
companyShareWithTax = json['CompanyShareWithTax'];
errCode = json['ErrCode'];
groupID = json['GroupID'];
insurancePolicyNo = json['InsurancePolicyNo'];
message = json['Message'];
patientCardID = json['PatientCardID'];
patientShare = json['PatientShare'];
patientShareWithTax = json['PatientShareWithTax'];
patientTaxAmount = json['PatientTaxAmount'];
policyId = json['PolicyId'];
policyName = json['PolicyName'];
procedureId = json['ProcedureId'];
procedureName = json['ProcedureName'];
setupID = json['SetupID'];
statusCode = json['StatusCode'];
subPolicyNo = json['SubPolicyNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['CashPrice'] = this.cashPrice;
data['CashPriceTax'] = this.cashPriceTax;
data['CashPriceWithTax'] = this.cashPriceWithTax;
data['CompanyId'] = this.companyId;
data['CompanyName'] = this.companyName;
data['CompanyShareWithTax'] = this.companyShareWithTax;
data['ErrCode'] = this.errCode;
data['GroupID'] = this.groupID;
data['InsurancePolicyNo'] = this.insurancePolicyNo;
data['Message'] = this.message;
data['PatientCardID'] = this.patientCardID;
data['PatientShare'] = this.patientShare;
data['PatientShareWithTax'] = this.patientShareWithTax;
data['PatientTaxAmount'] = this.patientTaxAmount;
data['PolicyId'] = this.policyId;
data['PolicyName'] = this.policyName;
data['ProcedureId'] = this.procedureId;
data['ProcedureName'] = this.procedureName;
data['SetupID'] = this.setupID;
data['StatusCode'] = this.statusCode;
data['SubPolicyNo'] = this.subPolicyNo;
return data;
}
}

@ -19,6 +19,9 @@ class GetAdmissionInfoResponseModel {
int? status; int? status;
String? statusDesc; String? statusDesc;
String? statusDescN; String? statusDescN;
String? clinicName;
String? doctorName;
String? projectName;
GetAdmissionInfoResponseModel( GetAdmissionInfoResponseModel(
{this.setupID, {this.setupID,
@ -40,7 +43,10 @@ class GetAdmissionInfoResponseModel {
this.approvalNo, this.approvalNo,
this.status, this.status,
this.statusDesc, this.statusDesc,
this.statusDescN}); this.statusDescN,
this.clinicName,
this.doctorName,
this.projectName});
GetAdmissionInfoResponseModel.fromJson(Map<String, dynamic> json) { GetAdmissionInfoResponseModel.fromJson(Map<String, dynamic> json) {
setupID = json['SetupID']; setupID = json['SetupID'];
@ -63,6 +69,9 @@ class GetAdmissionInfoResponseModel {
status = json['Status']; status = json['Status'];
statusDesc = json['StatusDesc']; statusDesc = json['StatusDesc'];
statusDescN = json['StatusDescN']; statusDescN = json['StatusDescN'];
clinicName = json['ClinicName'];
doctorName = json['DoctorName'];
projectName = json['ProjectName'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -87,6 +96,9 @@ class GetAdmissionInfoResponseModel {
data['Status'] = this.status; data['Status'] = this.status;
data['StatusDesc'] = this.statusDesc; data['StatusDesc'] = this.statusDesc;
data['StatusDescN'] = this.statusDescN; data['StatusDescN'] = this.statusDescN;
data['ClinicName'] = this.clinicName;
data['DoctorName'] = this.doctorName;
data['ProjectName'] = this.projectName;
return data; return data;
} }
} }

@ -24,6 +24,8 @@ class GetERAppointmentFeesList {
String? companyName; String? companyName;
bool? isInsured; bool? isInsured;
bool? isShowInsuranceUpdateModule; bool? isShowInsuranceUpdateModule;
bool? isCash;
bool? isEligible;
String? tax; String? tax;
String? total; String? total;
String? currency; String? currency;
@ -41,6 +43,8 @@ class GetERAppointmentFeesList {
amount = json['Amount']; amount = json['Amount'];
companyName = json['CompanyName']; companyName = json['CompanyName'];
isInsured = json['IsInsured']; isInsured = json['IsInsured'];
isCash = json['IsCash'];
isEligible = json['IsEligible'];
isShowInsuranceUpdateModule = json['IsShowInsuranceUpdateModule']; isShowInsuranceUpdateModule = json['IsShowInsuranceUpdateModule'];
tax = json['Tax']; tax = json['Tax'];
total = json['Total']; total = json['Total'];

@ -6,7 +6,7 @@ class IncomingCallData {
String? notificationForeground; String? notificationForeground;
String? count; String? count;
String? message; String? message;
String? appointmentNo; String? appointmentNo; // 1 for Video call, 2 for Audio call
String? title; String? title;
String? projectID; String? projectID;
String? notificationType; String? notificationType;

@ -8,7 +8,7 @@ class WeeklyHeartRateResModel {
{this.valueAvg, this.machineDate, this.medCategoryID, this.patientID}); {this.valueAvg, this.machineDate, this.medCategoryID, this.patientID});
WeeklyHeartRateResModel.fromJson(Map<String, dynamic> json) { WeeklyHeartRateResModel.fromJson(Map<String, dynamic> json) {
num value = json['ValueAvg']; num value = json['ValueAvg'] != null ? json['ValueAvg'] : 0.0;
valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; valueAvg = json['ValueAvg'] != null ? value.toInt() : 0;
machineDate = json['MachineDate']; machineDate = json['MachineDate'];
medCategoryID = json['MedCategoryID']; medCategoryID = json['MedCategoryID'];

@ -15,7 +15,7 @@ class YearlyHeartRateResModel {
this.year}); this.year});
YearlyHeartRateResModel.fromJson(Map<String, dynamic> json) { YearlyHeartRateResModel.fromJson(Map<String, dynamic> json) {
num value = json['ValueAvg']; num value = json['ValueAvg'] != null ? json['ValueAvg'] : 0.0;
valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; valueAvg = json['ValueAvg'] != null ? value.toInt() : 0;
medCategoryID = json['MedCategoryID']; medCategoryID = json['MedCategoryID'];
month = json['Month']; month = json['Month'];

@ -100,7 +100,7 @@ class ConfirmDialog extends StatelessWidget {
onClick(); onClick();
Navigator.pop(context); Navigator.pop(context);
}, },
textColor: Theme.of(context).backgroundColor), textColor: CustomColors.white),
), ),
], ],
), ),

@ -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/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/core/viewModels/all_habib_medical_services/e_referral_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.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/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
@ -367,11 +368,11 @@ class _EReferralConfirmSMSDialogState extends State<EReferralConfirmSMSDialog> {
), ),
errorBorder: OutlineInputBorder( errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)), borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor), borderSide: BorderSide(color: CustomColors.accentColor),
), ),
focusedErrorBorder: OutlineInputBorder( focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)), borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor), borderSide: BorderSide(color: CustomColors.accentColor),
), ),
); );
} }

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
@ -36,9 +37,7 @@ class HomeHealthCareIndexPage extends StatelessWidget {
SizedBox( SizedBox(
height: 22, height: 22,
), ),
Center( Center(child: Image.asset('assets/images/AlHabibMedicalService/Wifi-AR.png')),
child: Image.asset(
'assets/images/AlHabibMedicalService/Wifi-AR.png')),
SizedBox( SizedBox(
height: 77, height: 77,
), ),
@ -53,13 +52,13 @@ class HomeHealthCareIndexPage extends StatelessWidget {
width: MediaQuery.of(context).size.width * 0.9, width: MediaQuery.of(context).size.width * 0.9,
child: SecondaryButton( child: SecondaryButton(
onTap: () => Navigator.push( onTap: () => Navigator.push(
context, context,
FadePage( FadePage(
page: HomeHealthCarePage(), page: HomeHealthCarePage(),
), ),
), ),
label: TranslationBase.of(context).loginRegister, label: TranslationBase.of(context).loginRegister,
textColor: Theme.of(context).backgroundColor), textColor: CustomColors.white),
), ),
], ],
), ),

@ -37,6 +37,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
AuthProvider authProvider = new AuthProvider(); AuthProvider authProvider = new AuthProvider();
WeatherService _weatherService = WeatherService(); WeatherService _weatherService = WeatherService();
double weatherNum = 30; double weatherNum = 30;
late ProjectViewModel projectViewModel;
@override @override
void initState() { void initState() {
@ -235,7 +236,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, false); return ServicesView(hmgServices[index], index, false, projectViewModel);
}, },
), ),
), ),

@ -1,4 +1,5 @@
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_page.dart'; 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/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
@ -57,9 +58,7 @@ class H2OPageIndexPage extends StatelessWidget {
onTap: () => onTap: () =>
Navigator.push(context, FadePage(page: H2OPage())), Navigator.push(context, FadePage(page: H2OPage())),
label: "Water Tracker", label: "Water Tracker",
textColor: Theme textColor: CustomColors.white),
.of(context)
.backgroundColor),
), ),
], ],
), ),

@ -4,31 +4,57 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter/webview_flutter.dart';
class MyWebView extends StatelessWidget { class MyWebView extends StatefulWidget {
final String title; final String title;
final String selectedUrl; final String selectedUrl;
final Completer<WebViewController> _controller = Completer<WebViewController>();
MyWebView({ MyWebView({
required this.title, required this.title,
required this.selectedUrl, required this.selectedUrl,
}); });
@override @override
Widget build(BuildContext context) { State<MyWebView> createState() => _MyWebViewState();
return AppScaffold( }
isShowAppBar: true,
appBarTitle: title, class _MyWebViewState extends State<MyWebView> {
isShowDecPage: false, // final Completer<WebViewController> _controller = Completer<WebViewController>();
showNewAppBar: true, late final WebViewController _controller;
showNewAppBarTitle: true,
body: WebView( @override
initialUrl: selectedUrl, void initState() {
javascriptMode: JavascriptMode.unrestricted, super.initState();
onWebViewCreated: (WebViewController webViewController) { _controller = WebViewController()
_controller.complete(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);
// },
);
} }
} }

@ -445,7 +445,7 @@ class _BloodDonationBookAppointmentState extends State<BloodDonationBookAppointm
_events!.forEach((key, value) { _events!.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); 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; return meetings;
} }
@ -492,11 +492,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { 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; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -8,6 +8,7 @@ import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobi
import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.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/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
@ -350,11 +351,11 @@ class _ConfirmSMSDialogState extends State<ConfirmSMSDialog> {
), ),
errorBorder: OutlineInputBorder( errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)), borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor), borderSide: BorderSide(color: CustomColors.accentColor),
), ),
focusedErrorBorder: OutlineInputBorder( focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)), borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor), borderSide: BorderSide(color: CustomColors.accentColor),
), ),
); );
} }

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -183,7 +184,8 @@ class _NewTextFieldsState extends State<NewTextFields> {
validator: widget.validator, validator: widget.validator,
onSaved: widget.onSaved, 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 inputFormatters: widget.keyboardType == TextInputType.phone
? <TextInputFormatter>[ ? <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly, FilteringTextInputFormatter.digitsOnly,
@ -193,8 +195,8 @@ class _NewTextFieldsState extends State<NewTextFields> {
decoration: InputDecoration( decoration: InputDecoration(
labelText: widget.hintText, labelText: widget.hintText,
labelStyle: TextStyle(color: Colors.black), 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)), errorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.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)), 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)), 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)), disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(

@ -1,26 +1,38 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; 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/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.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/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/insurance/insurance_update_screen.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.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/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.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/new_design/doctor_header.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.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:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../models/Appointments/PatientPackageComponent.dart';
import 'book_reminder_page.dart'; import 'book_reminder_page.dart';
import 'components/DocAvailableAppointments.dart'; import 'components/DocAvailableAppointments.dart';
@ -41,7 +54,10 @@ class BookConfirm extends StatefulWidget {
bool isLiveCareAppointment; bool isLiveCareAppointment;
int initialSlotDuration; 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 DoctorsListService service;
late PatientShareResponse patientShareResponse; late PatientShareResponse patientShareResponse;
@ -62,6 +78,13 @@ class _BookConfirmState extends State<BookConfirm> {
bool isEligible = false; bool isEligible = false;
bool isCash = false; bool isCash = false;
String? selectedPaymentMethod = "";
String? selectedInstallments = "";
String? tamaraPaymentStatus;
String? tamaraOrderID;
String? transID;
late MyInAppBrowser browser;
@override @override
void initState() { void initState() {
// widget.authUser = new AuthenticatedUser(); // widget.authUser = new AuthenticatedUser();
@ -212,13 +235,19 @@ class _BookConfirmState extends State<BookConfirm> {
elevation: 0, elevation: 0,
onPressed: () async { onPressed: () async {
bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false;
if (isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor); if (widget.isWalkinAppointment) {
getWalkinAppointmentPatientShare();
} else { } 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<BookConfirm> {
); );
} }
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<PayfortViewModel>().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<PayfortViewModel>().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<PayfortViewModel>().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<String?> 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) { Widget showInfo(String title, String des) {
return Container( return Container(
child: Row( child: Row(
@ -253,7 +680,7 @@ class _BookConfirmState extends State<BookConfirm> {
); );
} }
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); ConfirmDialog.closeAlertDialog(context);
GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false);
DoctorsListService service = new DoctorsListService(); DoctorsListService service = new DoctorsListService();
@ -265,7 +692,7 @@ class _BookConfirmState extends State<BookConfirm> {
if (isLiveCareSchedule != null && isLiveCareSchedule) { if (isLiveCareSchedule != null && isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor); insertLiveCareScheduledAppointment(context, widget.doctor);
} else { } else {
insertAppointment(context, widget.doctor, widget.initialSlotDuration); insertAppointment(context, widget.doctor, widget.initialSlotDuration, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo, invoiceNoVP: invoiceNoVP);
} }
}); });
} else { } else {
@ -290,7 +717,7 @@ class _BookConfirmState extends State<BookConfirm> {
okText: "Update insurance", okText: "Update insurance",
cancelText: "Continue as cash", cancelText: "Continue as cash",
okFunction: () => {openUpdateInsurance()}, okFunction: () => {openUpdateInsurance()},
cancelFunction: () => {continueAsCash(docObject, appointmentNo)}); cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
}).catchError((err) { }).catchError((err) {
@ -304,23 +731,172 @@ class _BookConfirmState extends State<BookConfirm> {
Navigator.push(context, FadePage(page: InsuranceUpdate())); Navigator.push(context, FadePage(page: InsuranceUpdate()));
} }
void continueAsCash(DoctorList docObject, String appointmentNo) { void continueAsCash(DoctorList docObject, String appointmentNo, bool isLiveCareAppointment) {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
widget.service.convertPatientToCash(docObject.projectID!).then((res) { widget.service.convertPatientToCash(docObject.projectID!).then((res) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
if (res["MessageStatus"] == 1) { 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(); getToDoCount();
} else { } else {
AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); 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) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
print(err); 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; final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
String logs = await sharedPref.getString('selectedLogSlots'); String logs = await sharedPref.getString('selectedLogSlots');
List<dynamic> decodedLogs = json.decode(logs); List<dynamic> decodedLogs = json.decode(logs);
@ -329,7 +905,7 @@ class _BookConfirmState extends State<BookConfirm> {
widget.service 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, context, 'null', null, null, projectViewModel)
.insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context, .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) { .then((res) {
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess);
@ -366,14 +942,14 @@ class _BookConfirmState extends State<BookConfirm> {
confirmMessage: res['ErrorEndUserMessage'], confirmMessage: res['ErrorEndUserMessage'],
okText: TranslationBase.of(context).confirm, okText: TranslationBase.of(context).confirm,
cancelText: TranslationBase.of(context).cancel_nocaps, cancelText: TranslationBase.of(context).cancel_nocaps,
okFunction: () => {cancelAppointment(docObject, appo, context)}, okFunction: () => {cancelAppointment(docObject, appo, context, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo)},
cancelFunction: () => {}, cancelFunction: () => {},
); );
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
}).catchError((err) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); 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); projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
} }
@ -476,7 +1052,7 @@ class _BookConfirmState extends State<BookConfirm> {
okText: TranslationBase.of(context).updateInsuranceText, okText: TranslationBase.of(context).updateInsuranceText,
cancelText: TranslationBase.of(context).continueCash, cancelText: TranslationBase.of(context).continueCash,
okFunction: () => {openUpdateInsurance()}, okFunction: () => {openUpdateInsurance()},
cancelFunction: () => {continueAsCash(docObject, appointmentNo)}); cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
} }
@ -491,10 +1067,40 @@ class _BookConfirmState extends State<BookConfirm> {
} }
getLiveCareAppointmentPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { 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.service.getLiveCareAppointmentPatientShare(appointmentNo, clinicID, projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) {
widget.patientShareResponse = new PatientShareResponse.fromJson(res); widget.patientShareResponse = new PatientShareResponse.fromJson(res);
GifLoaderDialogUtils.hideDialog(context); 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) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err); AppToast.showErrorToast(message: err);
@ -575,4 +1181,32 @@ class _BookConfirmState extends State<BookConfirm> {
), ),
); );
} }
Future<void> _showMyDialog(String message, BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(message),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route<dynamic> r) => false);
},
),
],
);
},
);
}
} }

@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart';
import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.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/pages/MyAppointments/SchedulePage.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
@ -520,15 +521,9 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
// if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) { // if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) {
// navigateToDentalComplaints(context); // navigateToDentalComplaints(context);
// } else { // } else {
if (DocAvailableAppointments.areSlotsAvailable) { if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
if (projectViewModel.isLogin) { if (projectViewModel.isLogin) {
if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) { canPayForWalkInAppointment();
navigateToDentalComplaints(context);
} else {
final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
navigateToBookConfirm(context);
projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
}
} else { } else {
ConfirmDialog dialog = new ConfirmDialog( ConfirmDialog dialog = new ConfirmDialog(
context: context, context: context,
@ -539,9 +534,30 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
cancelFunction: () => {}); cancelFunction: () => {});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
} else } else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); if (DocAvailableAppointments.areSlotsAvailable) {
// } 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);
}
} 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 navigateToDentalComplaints(BuildContext context) async { Future navigateToDentalComplaints(BuildContext context) async {
@ -586,8 +602,33 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
selectedDate: DocAvailableAppointments.selectedDate!, selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!, selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: DocAvailableAppointments.initialSlotDuration!, 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);
});
}
} }

@ -387,7 +387,7 @@ class _QRCodeState extends State<QRCode> {
DoctorsListService service = new DoctorsListService(); 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); print(res);
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);

@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByDoctor.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/location_util.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
@ -28,15 +29,20 @@ class _SearchState extends State<Search> with TickerProviderStateMixin {
@override @override
void initState() { void initState() {
_tabController = new TabController(length: 2, vsync: this, initialIndex: widget.type, ); _tabController = new TabController(
length: 3,
vsync: this,
initialIndex: widget.type,
);
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppGlobal.context = context; AppGlobal.context = context;
// ProjectViewModel projectViewModel = Provider.of(context); // ProjectViewModel projectViewModel = Provider.of(context);
GAnalytics.TREATMENT_TYPE = null; // reset treatment type on start new booking GAnalytics.TREATMENT_TYPE =
null; // reset treatment type on start new booking
return AppScaffold( return AppScaffold(
isShowAppBar: false, isShowAppBar: false,
@ -54,32 +60,58 @@ class _SearchState extends State<Search> with TickerProviderStateMixin {
indicatorSize: TabBarIndicatorSize.tab, indicatorSize: TabBarIndicatorSize.tab,
labelColor: Color(0xff2B353E), labelColor: Color(0xff2B353E),
unselectedLabelColor: Color(0xff575757), 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( labelStyle: TextStyle(
fontFamily: context.read<ProjectViewModel>().isArabic ? 'Cairo' : 'Poppins', fontFamily: context.read<ProjectViewModel>().isArabic
? 'Cairo'
: 'Poppins',
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
letterSpacing: -0.48, letterSpacing: -0.48,
), ),
unselectedLabelStyle: TextStyle( unselectedLabelStyle: TextStyle(
fontFamily: context.read<ProjectViewModel>().isArabic ? 'Cairo' : 'Poppins', fontFamily: context.read<ProjectViewModel>().isArabic
? 'Cairo'
: 'Poppins',
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
letterSpacing: -0.48, 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) { onTap: (idx) {
if (idx == 0) if (idx == 0)
context.read<ProjectViewModel>().analytics.appointment.book_appointment_by_clinic(); context
.read<ProjectViewModel>()
.analytics
.appointment
.book_appointment_by_clinic();
else else
context.read<ProjectViewModel>().analytics.appointment.book_appointment_by_doctor(); context
.read<ProjectViewModel>()
.analytics
.appointment
.book_appointment_by_doctor();
}, },
), ),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
children: [ children: [
SearchByHospital(),
SearchByClinic(clnicIds: widget.clnicIds), SearchByClinic(clnicIds: widget.clnicIds),
SearchByDoctor(), SearchByDoctor(),
], ],

@ -60,6 +60,8 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
var language; var language;
bool isLiveCareSchedule = false; bool isLiveCareSchedule = false;
bool isWaitingAppointmentAvailable = false;
// String selectedLogSlots =''; // String selectedLogSlots ='';
@override @override
@ -198,7 +200,7 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
_events.forEach((key, value) { _events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(hours: 2)); 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; return meetings;
} }
@ -206,7 +208,9 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
openTimeSlotsPickerForDate(DateTime dateStart, List<TimeSlot> freeSlots) { openTimeSlotsPickerForDate(DateTime dateStart, List<TimeSlot> freeSlots) {
dayEvents.clear(); dayEvents.clear();
DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); 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) { freeSlots.forEach((v) {
if (v.start == dateStartObj) dayEvents.add(v); if (v.start == dateStartObj) dayEvents.add(v);
}); });
@ -276,23 +280,27 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
selectedDateJSON = freeSlotsResponse[0]; selectedDateJSON = freeSlotsResponse[0];
}); });
openTimeSlotsPickerForDate( 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.convertStringToDate(selectedDateJSON)
: DateUtil.convertStringToDateSaudiTimezone( : DateUtil.convertStringToDateSaudiTimezone(
selectedDateJSON, selectedDateJSON,
int.parse( int.parse(
widget.doctor.projectID.toString(), 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; _calendarController.displayDate = _calendarController.selectedDate;
return _eventsParsed; return _eventsParsed;
} }
@ -323,10 +331,10 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
Widget getSelectedButton(int index) { Widget getSelectedButton(int index) {
return CustomTextButton( return CustomTextButton(
backgroundColor: CustomColors.green, backgroundColor: dayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green,
elevation: 0, elevation: 0,
side: BorderSide( 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 style: BorderStyle.solid, //Style of the border
width: 1.5 //width of the border width: 1.5 //width of the border
), ),
@ -349,21 +357,23 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
if (res['FreeTimeSlots'].length != 0) { if (res['FreeTimeSlots'].length != 0) {
isWaitingAppointmentAvailable = res['IsAllowToBookWaitingAppointment']; // true;
// isWaitingAppointmentAvailable = true; // true;
DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration'];
DocAvailableAppointments.areAppointmentsAvailable = true; DocAvailableAppointments.areAppointmentsAvailable = true;
freeSlotsResponse = res['FreeTimeSlots']; freeSlotsResponse = res['FreeTimeSlots'];
_getJSONSlots().then((value) { _getJSONSlots().then((value) {
setState(() => { setState(() {
_events.clear(), _events.clear();
_events = value, _events = value;
if (widget.doctorSchedule != null) if (widget.doctorSchedule != null) {
{ _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date']));
_onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])), _calendarController.selectedDate = DateUtil.convertStringToDate(
_calendarController.selectedDate = DateUtil.convertStringToDate( widget.doctorSchedule['Date'],
widget.doctorSchedule['Date'], );
) }
} ;
}); });
}); });
} else { } else {
DocAvailableAppointments.areAppointmentsAvailable = false; DocAvailableAppointments.areAppointmentsAvailable = false;
@ -464,11 +474,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { 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; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -1,6 +1,7 @@
import "dart:collection"; import "dart:collection";
import 'package:auto_size_text/auto_size_text.dart'; 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/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
@ -95,6 +96,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppGlobal.context = context;
return Container( return Container(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
@ -648,7 +650,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
doctorsList.forEach((element) { doctorsList.forEach((element) {
List<PatientDoctorAppointmentList> doctorByHospital = _patientDoctorAppointmentListHospital List<PatientDoctorAppointmentList> doctorByHospital = _patientDoctorAppointmentListHospital
.where( .where(
(elementClinic) => elementClinic.filterName == element.projectName, (elementClinic) => elementClinic.filterName == element.getProjectCompleteName(),
) )
.toList(); .toList();
@ -656,7 +658,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
_patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element);
} else { } else {
_patientDoctorAppointmentListHospital _patientDoctorAppointmentListHospital
.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); .add(PatientDoctorAppointmentList(filterName: element.getProjectCompleteName(), distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element));
} }
}); });
} else {} } else {}

@ -105,13 +105,13 @@ class _SearchByDoctorState extends State<SearchByDoctor> {
}); });
doctorsList.forEach((element) { doctorsList.forEach((element) {
List<PatientDoctorAppointmentList> doctorByHospital = _patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.projectName).toList(); List<PatientDoctorAppointmentList> doctorByHospital = _patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.getProjectCompleteName()).toList();
if (doctorByHospital.length != 0) { if (doctorByHospital.length != 0) {
_patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element);
} else { } else {
_patientDoctorAppointmentListHospital _patientDoctorAppointmentListHospital
.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); .add(PatientDoctorAppointmentList(filterName: element.getProjectCompleteName(), distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element));
} }
}); });
} else { } else {

@ -0,0 +1,559 @@
import 'dart:collection';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/config/config.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<SearchByHospital> createState() => _SearchByHospitalState();
}
class _SearchByHospitalState extends State<SearchByHospital> {
HospitalsModel? selectedHospital;
bool nearestAppo = false;
String? selectedClinicName;
List<HospitalsModel> projectsList = [];
List<ListClinicCentralized>? clinicIds = List.empty();
final GlobalKey projectDropdownKey = GlobalKey();
List<ListClinicCentralized> 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: <Widget>[
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<HospitalsModel>(
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<HospitalsModel>(
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<ProjectViewModel>()
.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<ProjectViewModel>().isArabic ? 1 : 2;
ClinicListService service = new ClinicListService();
List<HospitalsModel> 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<HospitalsModel> projectsListLocal = [];
setState(() {
clinicIds = List.empty();
});
List<ListClinicCentralized> 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<ProjectViewModel>().isArabic ? 1 : 2;
GifLoaderDialogUtils.showMyDialog(context);
List<DoctorList> doctorsList = [];
List<String> arr = [];
List<String> arrDistance = [];
List<String> result;
int numAll;
List<PatientDoctorAppointmentList> _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<PatientDoctorAppointmentList> 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<String>.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<DoctorList> docList,
List<PatientDoctorAppointmentList>
patientDoctorAppointmentListHospital) async {
Navigator.push(
context,
FadePage(
page: SearchResults(
isLiveCareAppointment: false,
doctorsList: docList,
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: LaserBooking(),
),
).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<ProjectViewModel>().isLogin) {
if (context.read<ProjectViewModel>().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]));
}
}
}

@ -115,7 +115,7 @@ class _ClickListDialogState extends State<ClickListDialog> {
), ),
), ),
), ),
tempClinicsList[index].isLiveCareClinicAndOnline! tempClinicsList[index].isLiveCareClinicAndOnline == true
? SvgPicture.asset( ? SvgPicture.asset(
'assets/images/new-design/video_icon_green_right.svg', 'assets/images/new-design/video_icon_green_right.svg',
height: 12, height: 12,

@ -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,
),
),
),
);
}
}

@ -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<WaitingAppointmentVerification> createState() => _WaitingAppointmentVerificationState();
}
class _WaitingAppointmentVerificationState extends State<WaitingAppointmentVerification> {
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<GAnalytics>().todoList.to_do_list_nfc_cancel(widget.appointment!);
});
});
}
startQRCodeScan() async {
String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent));
if (onlineCheckInQRCode != "") {
checkScannedNFCAndQRCode(onlineCheckInQRCode);
} else {}
}
}

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
@ -44,10 +45,10 @@ showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, S
} }
} }
Future<void> _showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, Future<void> _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 { {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async {
return showDialog<void>( return showDialog<void>(
context: context, context: providedContext,
barrierDismissible: true, // user must tap button! barrierDismissible: true, // user must tap button!
builder: (BuildContext context) { builder: (BuildContext context) {
return Dialog( return Dialog(
@ -81,7 +82,7 @@ Future<void> _showReminderDialog(BuildContext context, DateTime dateTime, String
if (onMultiDateSuccess == null) { if (onMultiDateSuccess == null) {
CalendarUtils calendarUtils = await CalendarUtils.getInstance(); CalendarUtils calendarUtils = await CalendarUtils.getInstance();
await calendarUtils.createOrUpdateEvent( await calendarUtils.createOrUpdateEvent(
title: title ?? TranslationBase.of(context).reminderTitle + " " + doctorName, title: title ?? TranslationBase.of(providedContext).reminderTitle + " " + doctorName,
description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted,
scheduleDateTime: dateTime, scheduleDateTime: dateTime,
eventId: eventId); eventId: eventId);

@ -260,7 +260,7 @@ class _CovidTimeSlotsState extends State<CovidTimeSlots> with TickerProviderStat
_events.forEach((key, value) { _events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); 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; return meetings;
} }
@ -584,11 +584,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { 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; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -0,0 +1,203 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.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/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:provider/provider.dart';
class EROnlineCheckInBookAppointment extends StatefulWidget {
const EROnlineCheckInBookAppointment();
@override
State<EROnlineCheckInBookAppointment> createState() => _EROnlineCheckInBookAppointmentState();
}
class _EROnlineCheckInBookAppointmentState extends State<EROnlineCheckInBookAppointment> with SingleTickerProviderStateMixin {
late ProjectViewModel projectViewModel;
List<HospitalsModel> projectsList = [];
final GlobalKey projectDropdownKey = GlobalKey();
HospitalsModel? selectedHospital;
String projectDropdownValue = "";
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
getProjectsList();
});
super.initState();
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
return AppScaffold(
isShowAppBar: true,
appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}",
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
backgroundColor: Color(0xffF8F8F8),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: () {
openDropdown(projectDropdownKey);
},
child: Container(
width: double.infinity,
decoration: containerRadius(Colors.white, 12),
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,
child: DropdownButtonHideUnderline(
child: DropdownButton<HospitalsModel>(
key: projectDropdownKey,
hint: new Text(TranslationBase.of(context).selectHospital),
value: selectedHospital,
iconSize: 0,
isExpanded: true,
style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black),
items: projectsList.map((item) {
return new DropdownMenuItem<HospitalsModel>(
value: item,
child: new Text(item.name!),
);
}).toList(),
onChanged: (newValue) async {
setState(() {
selectedHospital = newValue;
projectDropdownValue = newValue!.mainProjectID.toString();
});
},
),
),
),
],
),
),
Icon(Icons.keyboard_arrow_down),
],
),
),
),
mHeight(16),
Container(
width: double.infinity,
decoration: containerRadius(Colors.white, 12),
padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
TranslationBase.of(context).clinicName,
style: TextStyle(
fontSize: 11,
letterSpacing: -0.44,
fontWeight: FontWeight.w600,
),
),
Text(
"ER Clinic",
style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black),
),
],
),
),
],
),
),
bottomSheet: Container(
height: 80,
color: CustomColors.white,
padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
child: DefaultButton(
TranslationBase.of(context).bookAppo,
() {
if (projectDropdownValue == "" || selectedHospital == null) {
AppToast.showErrorToast(message: TranslationBase.of(context).selectHospital);
} else {
Navigator.push(
context,
FadePage(
page: EROnlineCheckInPaymentDetails(
projectID: selectedHospital!.iD,
isERBookAppointment: true,
projectName: selectedHospital!.name ?? "",
),
),
);
}
},
color: CustomColors.accentColor,
),
),
);
}
getProjectsList() {
int languageID = projectViewModel.isArabic ? 1 : 2;
GifLoaderDialogUtils.showMyDialog(context);
ClinicListService service = new ClinicListService();
List<HospitalsModel> 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;
});
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
print(err);
});
}
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!();
}
}

@ -0,0 +1,451 @@
import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart';
import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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/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_nfc_kit/flutter_nfc_kit.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
class EROnlineCheckInHomePage extends StatefulWidget {
const EROnlineCheckInHomePage();
@override
State<EROnlineCheckInHomePage> createState() => _EROnlineCheckInHomePageState();
}
class _EROnlineCheckInHomePageState extends State<EROnlineCheckInHomePage> with SingleTickerProviderStateMixin {
late ProjectViewModel projectViewModel;
bool _supportsNFC = false;
bool isPatientArrived = false;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
// checkIfPatientHasArrived();
if (projectViewModel.isLogin) checkPatientERAdvanceBalance();
});
super.initState();
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
FlutterNfcKit.nfcAvailability.then((value) {
_supportsNFC = (value == NFCAvailability.available);
});
return AppScaffold(
isShowAppBar: true,
appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}",
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(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
Icons.check_circle,
size: 50,
color: CustomColors.green,
),
mHeight(6),
Text(
"What is Online Check-In?",
maxLines: 1,
style: TextStyle(
fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
),
Text(
"online check-in lets patients fill out forms, share insurance details, and book appointments online, making their visit smoother and quicker.",
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24),
),
mHeight(16),
Text(
"How can i use Online Check-In?",
maxLines: 1,
style: TextStyle(
fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
),
Text(
"online check-in lets patients fill out forms, share insurance details, and book appointments online, making their visit smoother and quicker.",
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24),
),
],
),
),
),
mHeight(24),
Container(
width: double.infinity,
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.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 35,
height: 35,
decoration: BoxDecoration(
color: CustomColors.green,
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Text(
"1",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24),
),
),
),
mWidth(12),
SvgPicture.asset(
"assets/images/new/tap.svg",
width: 35,
height: 35,
),
],
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Tap On",
maxLines: 1,
style: TextStyle(
fontSize: 20,
fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
fontWeight: FontWeight.w700,
color: Color(0xff2B353E),
letterSpacing: -1.44,
height: 35 / 24),
),
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Tap on the check-in button within the app",
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24),
),
),
mHeight(16),
Row(
children: [
Container(
width: 35,
height: 35,
decoration: BoxDecoration(
color: CustomColors.green,
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Text(
"2",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24),
),
),
),
mWidth(12),
SvgPicture.asset(
"assets/images/new/NFC_Hold.svg",
width: 35,
height: 35,
),
],
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Hold your phone",
maxLines: 1,
style: TextStyle(
fontSize: 20,
fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
fontWeight: FontWeight.w700,
color: Color(0xff2B353E),
letterSpacing: -1.44,
height: 35 / 24),
),
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Hold the phone 1 to 2 cm from the NFC sign displayed on the board",
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24),
),
),
mHeight(16),
Row(
children: [
Container(
width: 35,
height: 35,
decoration: BoxDecoration(
color: CustomColors.green,
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Text(
"3",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24),
),
),
),
mWidth(12),
SvgPicture.asset(
"assets/images/new/hourglass.svg",
width: 35,
height: 35,
),
],
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Wait your turn",
maxLines: 1,
style: TextStyle(
fontSize: 20,
fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
fontWeight: FontWeight.w700,
color: Color(0xff2B353E),
letterSpacing: -1.44,
height: 35 / 24),
),
),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
"Please wait in the waiting area until called by the nurse",
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24),
),
),
],
),
),
),
],
),
),
),
bottomSheet: Container(
height: projectViewModel.isLogin ? 80 : 1,
color: CustomColors.white,
padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
child: isPatientArrived
? Container(
child: DefaultButton(
TranslationBase.of(context).arrived,
() {
if (_supportsNFC) {
Future.delayed(const Duration(milliseconds: 500), () {
showNfcReader(context, onNcfScan: (String nfcId) {
Future.delayed(const Duration(milliseconds: 100), () {
print(nfcId);
getProjectIDFromNFC(nfcId, true);
// Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails()));
});
}, onCancel: () {
Navigator.of(context).pop();
});
});
} else {
//NFCNotSupported
AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported);
}
},
color: CustomColors.accentColor,
),
)
: Row(
children: [
Expanded(
flex: 1,
child: DefaultButton(
TranslationBase.of(context).checkinOptions,
() {
if (_supportsNFC) {
Future.delayed(const Duration(milliseconds: 500), () {
showNfcReader(context, onNcfScan: (String nfcId) {
Future.delayed(const Duration(milliseconds: 100), () {
print(nfcId);
getProjectIDFromNFC(nfcId, false);
});
}, onCancel: () {
Navigator.of(context).pop();
});
});
} else {
//NFCNotSupported
AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported);
}
},
color: CustomColors.green,
),
),
mWidth(12),
Expanded(
flex: 1,
child: DefaultButton(
TranslationBase.of(context).bookAppo,
() {
Navigator.push(context, FadePage(page: EROnlineCheckInBookAppointment()));
},
color: CustomColors.accentColor,
),
),
],
),
),
);
}
void getProjectIDFromNFC(String nfcID, bool isArrived) {
GifLoaderDialogUtils.showMyDialog(context);
ClinicListService ancillaryOrdersService = new ClinicListService();
ancillaryOrdersService.getProjectIDFromNFC(nfcID).then((response) {
if (response["GetProjectByNFC"].length != 0) {
print(response["GetProjectByNFC"]);
int projectID = response['GetProjectByNFC'][0]["ProjectID"];
String projectName = response['GetProjectByNFC'][0]["ProjectName"];
GifLoaderDialogUtils.hideDialog(context);
if (isArrived) {
autoGenerateInvoiceER(projectID);
} else {
Navigator.push(
context,
FadePage(
page: EROnlineCheckInPaymentDetails(
projectID: projectID,
isERBookAppointment: false,
projectName: projectName,
),
),
);
}
} else {
AppToast.showErrorToast(message: "Invalid NFC Card Scanned.");
}
}).catchError((err) {
AppToast.showErrorToast(message: err.toString());
GifLoaderDialogUtils.hideDialog(context);
});
}
autoGenerateInvoiceER(int projectID) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.autoGenerateInvoiceERClinic(projectID, 4, null, null, null, null, null, null, true).then((res) {
GifLoaderDialogUtils.hideDialog(context);
_showMyDialog(TranslationBase.of(context).ERCheckInSuccess, context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
Future<void> _showMyDialog(String message, BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(message),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route<dynamic> r) => false);
},
),
],
);
},
);
}
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);
});
}
void checkPatientERAdvanceBalance() {
GifLoaderDialogUtils.showMyDialog(context);
ClinicListService ancillaryOrdersService = new ClinicListService();
ancillaryOrdersService.checkPatientERAdvanceBalance(10).then((response) {
print(response["BalanceAmount"]);
isPatientArrived = response['BalanceAmount'] > 0;
GifLoaderDialogUtils.hideDialog(context);
setState(() {});
}).catchError((err) {
AppToast.showErrorToast(message: err.toString());
GifLoaderDialogUtils.hideDialog(context);
});
}
}

@ -0,0 +1,620 @@
import 'dart:developer';
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/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Clinics/EROnlineCheckInPaymentDetailsResponse.dart';
import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.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/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class EROnlineCheckInPaymentDetails extends StatefulWidget {
int projectID = 0;
bool isERBookAppointment = false;
String projectName = "";
EROnlineCheckInPaymentDetails({required this.projectID, required this.isERBookAppointment, required this.projectName});
@override
State<EROnlineCheckInPaymentDetails> createState() => _EROnlineCheckInPaymentDetailsState();
}
class _EROnlineCheckInPaymentDetailsState extends State<EROnlineCheckInPaymentDetails> with SingleTickerProviderStateMixin {
late ProjectViewModel projectViewModel;
EROnlineCheckInPaymentDetailsResponse? erOnlineCheckInPaymentDetailsResponse;
String? selectedPaymentMethod;
String? selectedInstallmentPlan;
String transID = "";
late MyInAppBrowser browser;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
getEROnlineCheckInPaymentDetails();
});
super.initState();
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
return AppScaffold(
isShowAppBar: true,
appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}",
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
backgroundColor: Color(0xffF8F8F8),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
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.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
TranslationBase.of(context).patientInfo,
style: TextStyle(
fontSize: 18, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
),
mHeight(12),
Row(
children: [
Text(
TranslationBase.of(context).patientName + ":",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
letterSpacing: -0.6,
color: CustomColors.grey,
),
),
mWidth(3),
Text(
projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
letterSpacing: -0.48,
),
),
],
),
Row(
children: [
Text(
TranslationBase.of(context).mrn + ":",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
letterSpacing: -0.6,
color: CustomColors.grey,
),
),
mWidth(3),
Text(
projectViewModel.user.patientID.toString(),
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
letterSpacing: -0.48,
),
),
],
),
],
),
),
),
mHeight(24),
Container(
width: double.infinity,
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.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"ER Visit Details",
style: TextStyle(
fontSize: 18, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
),
mHeight(12),
Row(
children: [
Text(
TranslationBase.of(context).hospital + ":",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
letterSpacing: -0.6,
color: CustomColors.grey,
),
),
mWidth(3),
Text(
widget.projectName,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
letterSpacing: -0.48,
),
),
],
),
Row(
children: [
Text(
TranslationBase.of(context).clinicName + ":",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
letterSpacing: -0.6,
color: CustomColors.grey,
),
),
mWidth(3),
Text(
"ER Clinic",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
letterSpacing: -0.48,
),
),
],
),
Row(
children: [
Text(
"Time Check-In" + ":",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
letterSpacing: -0.6,
color: CustomColors.grey,
),
),
mWidth(3),
Text(
DateUtil.getMonthDayYearDateFormatted(DateTime.now()),
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
letterSpacing: -0.48,
),
),
],
),
],
),
),
)
],
),
),
bottomSheet: erOnlineCheckInPaymentDetailsResponse != null
? 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).YouCanPayByTheFollowingOptions,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
letterSpacing: -0.64,
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.75,
child: getPaymentMethods(),
),
_amountView(TranslationBase.of(context).patientShareTotalToDo, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax.toString() + " " + TranslationBase.of(context).sar,
isBold: true, isTotal: true),
SizedBox(height: 12),
DefaultButton(
TranslationBase.of(context).payNow.toUpperCase(),
() {
makePayment();
},
color: CustomColors.green,
disabledColor: CustomColors.grey2,
),
],
),
)
: Container(),
);
}
makePayment() {
showDraggableDialog(
context,
PaymentMethod(
onSelectedMethod: (String method, [String? selectedInstallmentPlan]) {
selectedPaymentMethod = method;
this.selectedInstallmentPlan = selectedInstallmentPlan;
if (selectedPaymentMethod == "ApplePay") {
if (projectViewModel.havePrivilege(103)) {
startApplePay();
} else {
AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
appo.projectID = widget.projectID;
openPayment(selectedPaymentMethod!, projectViewModel.user, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax!, AppoitmentAllHistoryResultList());
}
} else {
openPayment(selectedPaymentMethod!, projectViewModel.user, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax!, AppoitmentAllHistoryResultList());
}
},
patientShare: erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax,
isFromAdvancePayment: false,
),
);
}
openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo) {
transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!);
browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart);
browser.openPaymentBrowser(amount, "ER Online Check-In Payment", transID, widget.projectID.toString(), authenticatedUser.emailAddress!, paymentMethod, authenticatedUser.patientType,
authenticatedUser.firstName!, authenticatedUser.patientID, authenticatedUser, browser, false, "3", "", context);
}
onBrowserLoadStart(String url) {
print("onBrowserLoadStart");
print(url);
MyInAppBrowser.successURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = true;
return;
}
});
MyInAppBrowser.errorURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = false;
return;
}
});
}
onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) {
print("onBrowserExit Called!!!!");
checkPaymentStatus(appo);
}
void startApplePay() async {
transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!);
print("TransactionID: $transID");
GifLoaderDialogUtils.showMyDialog(context);
LiveCareService service = new LiveCareService();
ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest();
PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel;
await context.read<PayfortViewModel>().getProjectDetailsForPayfort(projectId: widget.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) {
payfortProjectDetailsRespModel = value!;
});
applePayInsertRequest.clientRequestID = transID;
applePayInsertRequest.clinicID = 0;
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 = 0;
applePayInsertRequest.projectID = widget.projectID.toString();
applePayInsertRequest.serviceID = ServiceTypeEnum.advancePayment.getIdFromServiceEnum().toString();
applePayInsertRequest.channelID = 3;
applePayInsertRequest.patientID = projectViewModel.user.patientID;
applePayInsertRequest.patientTypeID = projectViewModel.user.patientType;
applePayInsertRequest.patientOutSA = projectViewModel.user.outSA;
applePayInsertRequest.appointmentDate = null;
applePayInsertRequest.appointmentNo = 0;
applePayInsertRequest.orderDescription = "ER Online Check-In Payment";
applePayInsertRequest.liveServiceID = "0";
applePayInsertRequest.latitude = "0.0";
applePayInsertRequest.longitude = "0.0";
applePayInsertRequest.amount = erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax.toString();
applePayInsertRequest.isSchedule = "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<PayfortViewModel>().initiateApplePayWithPayfort(
customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!,
// customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress,
customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com",
orderDescription: "ER Online Check-In Payment",
orderAmount: erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax,
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<PayfortViewModel>().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult);
GifLoaderDialogUtils.hideDialog(context);
checkPaymentStatus(AppoitmentAllHistoryResultList());
},
projectId: widget.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);
});
}
checkPaymentStatus(AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.checkPaymentStatus(transID, false, context).then((res) {
String paymentInfo = res['Response_Message'];
if (paymentInfo == 'Success') {
GifLoaderDialogUtils.hideDialog(context);
if (widget.isERBookAppointment) {
// createAdvancePayment(res, appo);
ER_createAdvancePayment(res, appo);
} else {
autoGenerateInvoiceER(res);
}
} else {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: res['Response_Message']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
ER_createAdvancePayment(payment_res, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
String paymentReference = payment_res['Fort_id'].toString();
service.ER_createAdvancePayment(appo, widget.projectID.toString(), payment_res['Amount'], payment_res['Fort_id'], payment_res['PaymentMethod'], context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
addAdvancedNumberRequest(
// Utils.isVidaPlusProject(projectViewModel, widget.projectID)
// ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
// : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
res['ER_AdvancePaymentResponse']['AdvanceNumber'].toString(),
paymentReference,
0,
appo,
payment_res);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
createAdvancePayment(paymentRes, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
String paymentReference = paymentRes['Fort_id'].toString();
service.HIS_createAdvancePayment(appo, widget.projectID.toString(), paymentRes['Amount'], paymentRes['Fort_id'], paymentRes['PaymentMethod'], projectViewModel.user.patientType,
projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.patientID, context)
.then((res) {
addAdvancedNumberRequest(
Utils.isVidaPlusProject(projectViewModel, widget.projectID)
? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
: res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
paymentReference,
0,
appo,
paymentRes);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo, paymentRes) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (widget.isERBookAppointment) {
AppToast.showSuccessToast(message: "Your appointment has been booked successfully. Please perform Check-In once you arrive at the hospital.");
Navigator.pop(context);
Navigator.pop(context);
Navigator.pop(context);
} else {
autoGenerateInvoiceER(paymentRes);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err.toString());
print(err);
});
}
autoGenerateInvoiceER(res) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.autoGenerateInvoiceERClinic(widget.projectID, 4, res['Fort_id'], res['Amount'], res['PaymentMethod'], res['CardNumber'], res['Merchant_Reference'], res['RRN'], false).then((res) {
GifLoaderDialogUtils.hideDialog(context);
_showMyDialog(TranslationBase.of(context).ERCheckInSuccess, context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
Future<void> _showMyDialog(String message, BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(message),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route<dynamic> r) => false);
},
),
],
);
},
);
}
getEROnlineCheckInPaymentDetails() {
GifLoaderDialogUtils.showMyDialog(context);
ClinicListService ancillaryOrdersService = new ClinicListService();
ancillaryOrdersService.getEROnlineCheckInPaymentDetails(widget.projectID, 10).then((response) {
erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]);
GifLoaderDialogUtils.hideDialog(context);
setState(() {});
}).catchError((err) {
AppToast.showErrorToast(message: err.toString());
GifLoaderDialogUtils.hideDialog(context);
});
}
_amountView(String title, String value, {bool isBold = false, bool isTotal = false}) {
return Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(children: [
Expanded(
child: _getNormalText(title),
),
Expanded(
child: _getNormalText(value, isBold: isBold, isTotal: isTotal),
),
]),
);
}
_getNormalText(text, {bool isBold = false, bool isTotal = false}) {
return Text(
text,
style: TextStyle(
fontSize: isBold
? isTotal
? 16
: 12
: 11,
letterSpacing: -0.5,
color: isBold ? Color(0xff2E303A) : Color(0xff575757),
fontWeight: isTotal ? FontWeight.bold : FontWeight.w600,
),
);
}
}

@ -0,0 +1,218 @@
import 'package:auto_size_text/auto_size_text.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:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AdmissionNotice extends StatefulWidget {
const AdmissionNotice();
@override
State<AdmissionNotice> createState() => _AdmissionNoticeState();
}
class _AdmissionNoticeState extends State<AdmissionNotice> {
late ProjectViewModel projectViewModel;
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
List<Widget> 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<Widget> getAdmissionNoticeServicesList(BuildContext context) {
List<Widget> 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: <Widget>[
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,
),
),
],
);
});
}
}

@ -255,7 +255,8 @@ class _InPatientPendingAdvancePaymentState extends State<InPatientPendingAdvance
service service
.getInPatientPaymentLink( .getInPatientPaymentLink(
projectViewModel.inPatientProjectID, projectViewModel.inPatientProjectID,
projectViewModel.getAdmissionInfoResponseModel.admissionNo!, // projectViewModel.getAdmissionInfoResponseModel.admissionNo!,
projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!,
orderID, orderID,
projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!,
projectViewModel.user.emailAddress!, projectViewModel.user.emailAddress!,
@ -272,7 +273,7 @@ class _InPatientPendingAdvancePaymentState extends State<InPatientPendingAdvance
if (isCopy) { if (isCopy) {
Share.share(paymentLink); Share.share(paymentLink);
} else { } else {
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(paymentLink)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(paymentLink))), options: _InAppBrowserOptions);
} }
} else { } else {
AppToast.showErrorToast(message: res["endUserMessage"]); AppToast.showErrorToast(message: res["endUserMessage"]);

@ -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: <Widget>[
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);
});
}
}

@ -1,9 +1,11 @@
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/InPatientServices/get_general_instructions_response_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/birth_notification.dart';
import 'package:diplomaticquarterapp/pages/InPatientServices/general_instructions.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/general_instructions.dart';
import 'package:diplomaticquarterapp/pages/InPatientServices/help_PRO.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/help_PRO.dart';
import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_advance_payment.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/meal_plan.dart';
import 'package:diplomaticquarterapp/pages/InPatientServices/medical_instructions.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/medical_instructions.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
@ -78,6 +80,23 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
List<Widget> getInPatientServicesList(BuildContext context) { List<Widget> getInPatientServicesList(BuildContext context) {
List<Widget> serviceList = []; List<Widget> serviceList = [];
serviceList.add(
InkWell(
onTap: () {
openPatientGeneralConsent();
},
child: MedicalProfileItem(
title: TranslationBase.of(context).generalInstructionsTitle,
imagePath: 'general_instructions.svg',
subTitle: TranslationBase.of(context).consent,
width: 50.0,
height: 40.0,
isInPatient: true,
isEnable: true,
),
),
);
serviceList.add( serviceList.add(
InkWell( InkWell(
onTap: () { onTap: () {
@ -180,6 +199,23 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
), ),
); );
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( serviceList.add(
InkWell( InkWell(
onTap: () { onTap: () {
@ -241,18 +277,18 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
void checkDischargeMedications(BuildContext context) { void checkDischargeMedications(BuildContext context) {
ClinicListService service = new ClinicListService(); ClinicListService service = new ClinicListService();
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
// service.getDischargeMedicationOrder(projectViewModel.getAdmissionInfoResponseModel).then((res) { service.getDischargeMedicationOrder(projectViewModel.getAdmissionInfoResponseModel).then((res) {
// print(res["PatientHasDischargeMedicineList"].length); print(res["PatientHasDischargeMedicineList"].length);
// setState(() { setState(() {
// if (res["PatientHasDischargeMedicineList"].length != 0) { if (res["PatientHasDischargeMedicineList"].length != 0) {
// isReceivePrescriptionEnabled = true; isReceivePrescriptionEnabled = true;
// } }
// }); });
// GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
// }).catchError((err) { }).catchError((err) {
// GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
// print(err); print(err);
// }); });
} }
void callReceivePrescriptionAPI(BuildContext context) { void callReceivePrescriptionAPI(BuildContext context) {
@ -272,7 +308,7 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
void openBirthNotificationsPage(BuildContext context) { void openBirthNotificationsPage(BuildContext context) {
ClinicListService service = new ClinicListService(); ClinicListService service = new ClinicListService();
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
service.getBirthNotification(projectViewModel.user.patientID!, context).then((res) { service.getBirthNotification(projectViewModel.user.patientID!, projectViewModel.isArabic ? 1 : 2, context).then((res) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
if (res["MessageStatus"] == 1) { if (res["MessageStatus"] == 1) {
print(res['birthNotification']); print(res['birthNotification']);
@ -285,10 +321,14 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
}); });
} }
void openPatientGeneralConsent() {
Navigator.push(context, FadePage(page: InPatientGeneralConsent()));
}
void openGeneralInstructions(BuildContext context) { void openGeneralInstructions(BuildContext context) {
ClinicListService service = new ClinicListService(); ClinicListService service = new ClinicListService();
GifLoaderDialogUtils.showMyDialog(context); 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) { if (res['generalInstructions'].length != 0) {
List<GetGeneralInstructions> getGeneralInstructionsList = []; List<GetGeneralInstructions> getGeneralInstructionsList = [];
res['generalInstructions'].forEach((v) { res['generalInstructions'].forEach((v) {
@ -298,6 +338,7 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
print(res['generalInstructions']); print(res['generalInstructions']);
Navigator.push(context, FadePage(page: GeneralInstructions(getGeneralInstructionsList: getGeneralInstructionsList))); Navigator.push(context, FadePage(page: GeneralInstructions(getGeneralInstructionsList: getGeneralInstructionsList)));
} else { } else {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: TranslationBase.of(context).noGeneralInstructions); AppToast.showErrorToast(message: TranslationBase.of(context).noGeneralInstructions);
} }
}).catchError((err) { }).catchError((err) {
@ -308,7 +349,7 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
void openMedicalInstructions(BuildContext context) { void openMedicalInstructions(BuildContext context) {
ClinicListService service = new ClinicListService(); ClinicListService service = new ClinicListService();
GifLoaderDialogUtils.showMyDialog(context); 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) { if (res['MedicalInstruction'] != null && res['MedicalInstruction'].length != 0) {
List<GetMedicalInstructions> getMedicalInstructionsList = []; List<GetMedicalInstructions> getMedicalInstructionsList = [];
res['MedicalInstruction'].forEach((v) { res['MedicalInstruction'].forEach((v) {
@ -334,6 +375,7 @@ class _InPatientServicesHomeState extends State<InPatientServicesHome> {
projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!,
projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0,
projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!,
projectViewModel.isArabic ? 1 : 2,
context) context)
.then((res) { .then((res) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);

@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.
import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.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/pages/MyAppointments/SchedulePage.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
@ -299,23 +300,68 @@ class _AppointmentDetailsState extends State<AppointmentDetails> with SingleTick
} }
void goToBookConfirm() { void goToBookConfirm() {
if (DocAvailableAppointments.areSlotsAvailable) if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
navigateToBookConfirm(context); canPayForWalkInAppointment();
else } else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); 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 { Future navigateToBookConfirm(context) async {
Navigator.push( Navigator.push(
context, context,
FadePage( FadePage(
page: BookConfirm( page: BookConfirm(
doctor: getDoctorObject(), doctor: getDoctorObject(),
isLiveCareAppointment: widget.appo.isLiveCareAppointment!, isLiveCareAppointment: widget.appo.isLiveCareAppointment!,
selectedDate: DocAvailableAppointments.selectedDate!, selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!, selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: 0, initialSlotDuration: 0,
))); isWalkinAppointment: false,
),
),
);
} }
void getDoctorRatingsDetails() { void getDoctorRatingsDetails() {

@ -39,6 +39,7 @@ class BookedButtons {
"icon": "hosp_location.svg", "icon": "hosp_location.svg",
"caller": "navigateToProject", "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"}
]; ];
} }

@ -19,6 +19,7 @@ class ConfirmedButtons {
// "icon": "assets/images/new-design/generate_visit_ticket.png", // "icon": "assets/images/new-design/generate_visit_ticket.png",
// "caller": "visitTicket" // "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"}
]; ];
} }

@ -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/radiology/radiology_details_page.dart';
import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.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/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.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:huawei_map/huawei_map.dart' as hmsMap;
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:map_launcher/map_launcher.dart'; import 'package:map_launcher/map_launcher.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -178,6 +181,31 @@ class _AppointmentActionsState extends State<AppointmentActions> {
navigateToInsertComplaint(); navigateToInsertComplaint();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint'); locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint');
break; break;
case "goToNavigation":
initPenguinSDK();
locator<GAnalytics>().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<Permission, PermissionStatus> 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);
});
} }
} }

@ -253,7 +253,7 @@ class _CovidTimeSlotsState extends State<ObGyneTimeSlots> with TickerProviderSta
_events!.forEach((key, value) { _events!.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); 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; return meetings;
} }
@ -534,11 +534,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { 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; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -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_project_details_resp_model.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.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_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.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/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.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_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ToDo extends StatefulWidget { class ToDo extends StatefulWidget {
@ -354,23 +357,56 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16), style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16),
), ),
), ),
InkWell( Row(
onTap: () { mainAxisAlignment: MainAxisAlignment.spaceBetween,
navigateToAppointmentDetails(context, appoList[index]); children: [
}, InkWell(
child: Padding( onTap: () {
padding: const EdgeInsets.only(top: 0.0), navigateToAppointmentDetails(context, appoList[index]);
child: Text( },
TranslationBase.of(context).moreDetails, child: Padding(
style: TextStyle( padding: const EdgeInsets.only(top: 0.0),
fontSize: 10, child: Text(
fontWeight: FontWeight.w600, TranslationBase.of(context).moreDetails,
color: CustomColors.accentColor, style: TextStyle(
letterSpacing: -0.48, fontSize: 10,
height: 25 / 16, fontWeight: FontWeight.w600,
decoration: TextDecoration.underline), 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<ToDo> with SingleTickerProviderStateMixin {
); );
} }
initPenguinSDK(NavigationClinicDetails data) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> 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) { String getNextActionImage(nextAction) {
switch (nextAction) { switch (nextAction) {
case 0: case 0:
@ -949,7 +1000,7 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
okText: "Update insurance", okText: "Update insurance",
cancelText: "Continue as cash", cancelText: "Continue as cash",
okFunction: () => {openUpdateInsurance()}, okFunction: () => {openUpdateInsurance()},
cancelFunction: () => {continueAsCash(appo)}); cancelFunction: () => {continueAsCash(appo, false)});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
}).catchError((err) { }).catchError((err) {
@ -963,19 +1014,24 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
Navigator.push(context, FadePage(page: InsuranceUpdate())); Navigator.push(context, FadePage(page: InsuranceUpdate()));
} }
void continueAsCash(AppoitmentAllHistoryResultList appo) { void continueAsCash(AppoitmentAllHistoryResultList appo, bool isLiveCareAppointment) {
DoctorsListService service = new DoctorsListService(); DoctorsListService service = new DoctorsListService();
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
service.convertPatientToCash(appo.projectID!).then((res) { service.convertPatientToCash(appo.projectID!).then((res) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
if (res["MessageStatus"] == 1) { if (res["MessageStatus"] == 1) {
getPatientShare(context, appo); if (isLiveCareAppointment) {
getLiveCareAppointmentPatientShare(context, service, appo);
} else {
getPatientShare(context, appo);
}
// getToDoCount(); // getToDoCount();
} else { } else {
AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); AppToast.showErrorToast(message: res["ErrorEndUserMessage"]);
} }
}).catchError((err) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err); print(err);
}); });
} }
@ -1015,7 +1071,7 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
okText: TranslationBase.of(context).updateInsuranceText, okText: TranslationBase.of(context).updateInsuranceText,
cancelText: TranslationBase.of(context).continueCash, cancelText: TranslationBase.of(context).continueCash,
okFunction: () => {openUpdateInsurance()}, okFunction: () => {openUpdateInsurance()},
cancelFunction: () => {continueAsCash(appo)}); cancelFunction: () => {continueAsCash(appo, false)});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
} }
@ -1028,11 +1084,40 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
} }
getLiveCareAppointmentPatientShare(context, DoctorsListService service, AppoitmentAllHistoryResultList appo) { getLiveCareAppointmentPatientShare(context, DoctorsListService service, AppoitmentAllHistoryResultList appo) {
String errorMsg = "";
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
service.getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), appo.clinicID, appo.projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { service.getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), appo.clinicID, appo.projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
widget.patientShareResponse = new PatientShareResponse.fromJson(res); 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) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err); AppToast.showErrorToast(message: err);
@ -1114,7 +1199,6 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo);
} }
}); });
projectViewModel.analytics.todoList.to_do_list_pay_now(appo); projectViewModel.analytics.todoList.to_do_list_pay_now(appo);
} }
@ -1464,7 +1548,7 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
}).catchError((err) { }).catchError((err) {
print(err); print(err);
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err); AppToast.showErrorToast(message: err.toString());
}); });
} }

@ -472,7 +472,7 @@ class _CallScreenState extends State<CallScreen> {
], ],
), ),
); );
if (errorType == Errors.SessionJoinFailed) { if (errorType == Errors.SessionJoinFailed || errorType == Errors.SessionDisconnecting) {
Timer( Timer(
const Duration(milliseconds: 1000), const Duration(milliseconds: 1000),
() => Navigator.pop(context), () => Navigator.pop(context),

@ -167,7 +167,7 @@ class _InsuranceUpdateState extends State<InsuranceUpdate> with SingleTickerProv
Container( Container(
margin: EdgeInsets.only(top: 6.5, left: 2.0), margin: EdgeInsets.only(top: 6.5, left: 2.0),
child: Text( child: Text(
model.insuranceUpdate[index].statusDescription!, model.insuranceUpdate[index].statusDescription ?? "",
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,

@ -45,6 +45,9 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
// getPatientAppointmentHistory1();
// getFamilyFiles();
} }
initialiseHmgServices(bool isLogin) { initialiseHmgServices(bool isLogin) {
@ -52,7 +55,12 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); 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(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).emergencySubtitle, "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))
: 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));
hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); 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(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)); hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin));
@ -66,9 +74,17 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
// hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); // 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(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)); // 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))
: 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));
hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); 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(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(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(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)); hmgServices.add(new HmgServices(8, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.svg", isLogin));
@ -296,15 +312,16 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
child: ServicesView( child: ServicesView(
new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false), new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false),
23, 23,
true)), true,
projectViewModel)),
), ),
), ),
Expanded( Expanded(
flex: 4, flex: 4,
child: AspectRatio( child: AspectRatio(
aspectRatio: 1.0, aspectRatio: 1.0,
child: ServicesView( child: ServicesView(new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2,
new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, true)), true, projectViewModel)),
), ),
], ],
), ),
@ -322,7 +339,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, true); return ServicesView(hmgServices[index], index, true, projectViewModel);
}, },
), ),
), ),
@ -341,7 +358,8 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { 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);
}, },
), ),
), ),
@ -489,8 +507,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
flex: 1, flex: 1,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
if (projectViewModel.havePrivilege(100)) if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!();
widget.onPharmacyClick!();
}, },
child: Stack(children: [ child: Stack(children: [
Container( Container(

@ -33,6 +33,11 @@ class _HomePageState2 extends State<HomePage2> {
PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>(); PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>();
late ProjectViewModel projectViewModel; late ProjectViewModel projectViewModel;
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
projectViewModel = Provider.of(context); projectViewModel = Provider.of(context);

@ -44,7 +44,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart';
@ -76,8 +76,7 @@ class LandingPage extends StatefulWidget {
class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver { class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
var authProvider = new AuthProvider(); var authProvider = new AuthProvider();
AppointmentRateViewModel appointmentRateViewModel = AppointmentRateViewModel appointmentRateViewModel = locator<AppointmentRateViewModel>();
locator<AppointmentRateViewModel>();
int currentTab = 0; int currentTab = 0;
late PageController pageController; late PageController pageController;
@ -94,8 +93,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
bool _showBottomNavigationBar = true; bool _showBottomNavigationBar = true;
///inject the user data ///inject the user data
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
locator<AuthenticatedUserObject>();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final authService = new AuthProvider(); final authService = new AuthProvider();
@ -122,22 +120,17 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
"appointmentdate": "2022-01-19", "appointmentdate": "2022-01-19",
"appointmenttime": "12:10", "appointmenttime": "12:10",
"PatientName": "Testing", "PatientName": "Testing",
"session_id": "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg",
"1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg",
"token": "token":
"T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9",
"DoctorImageURL": "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg",
"https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg",
"callerID": "9920", "callerID": "9920",
"PatientID": "1231755", "PatientID": "1231755",
"is_call": "true" "is_call": "true"
}; };
void _requestIOSPermissions() { void _requestIOSPermissions() {
flutterLocalNotificationsPlugin flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true, alert: true,
badge: true, badge: true,
sound: true, sound: true,
@ -153,8 +146,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
return Future.value(false); return Future.value(false);
} else { } else {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
if (currentBackPressTime == null || if (currentBackPressTime == null || now.difference(currentBackPressTime!) > Duration(seconds: 2)) {
now.difference(currentBackPressTime!) > Duration(seconds: 2)) {
currentBackPressTime = now; currentBackPressTime = now;
AppToast.showToast(message: TranslationBase.of(context).pressAgain); AppToast.showToast(message: TranslationBase.of(context).pressAgain);
return Future.value(false); return Future.value(false);
@ -169,18 +161,14 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
List<ImagesInfo> imagesInfo = []; List<ImagesInfo> imagesInfo = [];
imagesInfo.add( imagesInfo.add(
ImagesInfo( ImagesInfo(
imageEn: imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png',
'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'),
imageAr:
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'),
); );
imagesInfo.add( imagesInfo.add(
ImagesInfo( ImagesInfo(
imageEn: imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png',
'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'),
imageAr:
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'),
); );
Navigator.push( Navigator.push(
@ -199,11 +187,8 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
} }
if (tab == 4) { if (tab == 4) {
List<ImagesInfo> imagesInfo = []; List<ImagesInfo> imagesInfo = [];
imagesInfo.add(ImagesInfo( imagesInfo.add(
imageEn: 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'));
'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( Navigator.push(
context, context,
@ -248,8 +233,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
}); });
}); });
projectViewModel.analytics.bottomTabNavigation projectViewModel.analytics.bottomTabNavigation.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin);
.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin);
} }
getToDoCount() { getToDoCount() {
@ -260,11 +244,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
print(res['AppointmentActiveNumber']); print(res['AppointmentActiveNumber']);
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
// toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount);
toDoProvider.setState( toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount);
res['AppointmentActiveNumber'],
res['AncillaryOrderListCount'],
true,
toDoProvider.notificationsCount);
} else {} } else {}
}).catchError((err) { }).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
@ -303,10 +283,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (projectViewModel.isLogin && !projectViewModel.isLoginChild) { if (projectViewModel.isLogin && !projectViewModel.isLoginChild) {
int languageID = int languageID = Provider.of<ProjectViewModel>(context, listen: false).isArabic ? 1 : 2;
Provider.of<ProjectViewModel>(context, listen: false).isArabic
? 1
: 2;
familyFileProvider.getSharedRecordByStatus(languageID); familyFileProvider.getSharedRecordByStatus(languageID);
} }
// Future.delayed(Duration(seconds: 3)).then((result) async { // Future.delayed(Duration(seconds: 3)).then((result) async {
@ -322,31 +299,34 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
// HMGNetworkConnectivity(context).start(); // HMGNetworkConnectivity(context).start();
_firebaseMessaging.getToken().then((String? token) { _firebaseMessaging.getToken().then((String? token) {
// print("Firebase Token: " + token!); // print("Firebase Token: " + token!);
sharedPref.setString(PUSH_TOKEN, token!); sharedPref.setString(PUSH_TOKEN, token!);
if (Platform.isIOS) { if (Platform.isIOS) {
FirebaseMessaging.instance.getAPNSToken().then((value) { FirebaseMessaging.instance.getAPNSToken().then((value) {
print("Push APNS getToken: " + value!); print("Push APNS getToken: " + value!);
AppSharedPreferences().setString(APNS_TOKEN, value); AppSharedPreferences().setString(APNS_TOKEN, value);
AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, value); AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, value);
}); });
// voIPKit.getVoIPToken().then((value) { // voIPKit.getVoIPToken().then((value) {
// print('🎈 example: getVoIPToken: $value'); // print('🎈 example: getVoIPToken: $value');
// AppSharedPreferences().setString(APNS_TOKEN, value!); // AppSharedPreferences().setString(APNS_TOKEN, value!);
// // getOneSignalVOIPToken(value); // // getOneSignalVOIPToken(value);
// }); // });
} }
if (token != null) { if (token != null) {
DEVICE_TOKEN = token; DEVICE_TOKEN = token;
if (!projectViewModel.isLoginChild) { if (!projectViewModel.isLoginChild) {
checkUserStatus(token); checkUserStatus(token);
} }
} }
}).catchError((err) {
print(err);
}); });
startZoom(); startZoom();
// HMG_Geofencing(context).loadZones().then((instance) => instance.init()); // HMG_Geofencing(context).loadZones().then((instance) => instance.init());
} }
void startZoom(){
void startZoom() {
var zoom = ZoomVideoSdk(); var zoom = ZoomVideoSdk();
InitConfig initConfig = InitConfig( InitConfig initConfig = InitConfig(
domain: "zoom.us", domain: "zoom.us",
@ -476,20 +456,14 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
getNotificationCount(token) async { getNotificationCount(token) async {
if (await sharedPref.getObject(USER_PROFILE) != null) { if (await sharedPref.getObject(USER_PROFILE) != null) {
var data = var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
if (data != null) { if (data != null) {
authService.getDashboard().then((value) => { authService.getDashboard().then((value) => {
if (value != null) if (value != null)
{ {
setState(() { setState(() {
notificationCount = value['List_PatientDashboard'][0] notificationCount =
['UnreadPatientNotificationCount'] > value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString();
99
? '99+'
: value['List_PatientDashboard'][0]
['UnreadPatientNotificationCount']
.toString();
model.setState(model.count, 0, true, notificationCount); model.setState(model.count, 0, true, notificationCount);
sharedPref.setString(NOTIFICATION_COUNT, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount);
}) })
@ -519,11 +493,9 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
getText(currentTab).toUpperCase(), getText(currentTab).toUpperCase(),
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: currentTab == 0 color: currentTab == 0 ? CustomColors.backgroudGreyColor : CustomColors.accentColor,
? CustomColors.backgroudGreyColor // : Theme.of(context).textTheme.headline1!.color,
: Theme.of(context).textTheme.headline1!.color, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
fontFamily:
projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
// bold: true, // bold: true,
), ),
leading: Builder( leading: Builder(
@ -532,14 +504,10 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
children: <Widget>[ children: <Widget>[
currentTab == 0 currentTab == 0
? IconButton( ? IconButton(
icon: SvgPicture.asset( icon: SvgPicture.asset("assets/images/new/menu.svg"),
"assets/images/new/menu.svg"), // color: Theme.of(context).textTheme.headline1!.color,
color: Theme.of(context) color: CustomColors.white,
.textTheme onPressed: () => Scaffold.of(context).openDrawer(),
.headline1!
.color,
onPressed: () =>
Scaffold.of(context).openDrawer(),
) )
: IconButton( : IconButton(
icon: Icon(Icons.arrow_back), icon: Icon(Icons.arrow_back),
@ -550,9 +518,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
pageController.jumpToPage(0); pageController.jumpToPage(0);
}, },
), ),
projectViewModel.isLogin && projectViewModel.isLogin && model.notificationsCount != null && !projectViewModel.isLoginChild
model.notificationsCount != null &&
!projectViewModel.isLoginChild
? Positioned( ? Positioned(
right: projectViewModel.isArabic ? 35 : 0, right: projectViewModel.isArabic ? 35 : 0,
top: 5, top: 5,
@ -570,8 +536,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
model.notificationsCount.toString(), model.notificationsCount.toString(),
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: fontSize: projectViewModel.isArabic ? 8 : 9,
projectViewModel.isArabic ? 8 : 9,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@ -655,16 +620,15 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
index: currentTab, index: currentTab,
), ),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: floatingActionButton: (projectViewModel.havePrivilege(34) && currentTab == 0)
(projectViewModel.havePrivilege(34) && currentTab == 0) ? FloatingButton(
? FloatingButton( elevation: true,
elevation: true, onTap: () {
onTap: () { changeCurrentTab(2);
changeCurrentTab(2); projectViewModel.analytics.appointment.book_appointment();
projectViewModel.analytics.appointment.book_appointment(); },
}, )
) : null);
: null);
} }
triggerRobot() { triggerRobot() {
@ -692,25 +656,16 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
await PushNotificationHandler.getInstance().requestPermissions(); await PushNotificationHandler.getInstance().requestPermissions();
// authService.selectDeviceImei(token).then((SelectDeviceIMEIRES? value) => setUserValues(value)); // authService.selectDeviceImei(token).then((SelectDeviceIMEIRES? value) => setUserValues(value));
if (authenticatedUserObject.isLogin) { if (authenticatedUserObject.isLogin) {
var data = var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
if (data != null) { if (data != null) {
authService authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {});
.registeredAuthenticatedUser(data, token, 0, 0)
.then((res) => {});
authService.getDashboard().then((value) async { authService.getDashboard().then((value) async {
setState(() { setState(() {
if (value != null) { if (value != null) {
notificationCount = value['List_PatientDashboard'][0] notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString();
['UnreadPatientNotificationCount'] >
99
? '99+'
: value['List_PatientDashboard'][0]
['UnreadPatientNotificationCount']
.toString();
model.setState(model.count, 0, true, notificationCount); model.setState(model.count, 0, true, notificationCount);
sharedPref.setString(NOTIFICATION_COUNT, 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)) { // if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) {

@ -4,7 +4,9 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/size_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/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/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/models/hmg_services.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart';
@ -21,6 +23,7 @@ import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_initial_page.
import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart';
import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart';
import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart';
import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart';
import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart';
import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_home.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_home.dart';
import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart';
@ -31,14 +34,20 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart
import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/theme/colors.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/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/location_util.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/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.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:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../locator.dart'; import '../../../locator.dart';
@ -52,8 +61,10 @@ class ServicesView extends StatelessWidget {
PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>(); PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>();
late LocationUtils locationUtils; late LocationUtils locationUtils;
bool isHomePage; 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -159,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<HospitalsModel> 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<Permission, PermissionStatus> 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) { handleHomePageServices(HmgServices hmgServices, BuildContext context) {
if (hmgServices.action == 0) { if (hmgServices.action == 0) {
Navigator.push(context, FadePage(page: Search())); Navigator.push(context, FadePage(page: Search()));
@ -172,8 +229,13 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 1) { } else if (hmgServices.action == 1) {
openLiveCare(context); openLiveCare(context);
} else if (hmgServices.action == 2) { } else if (hmgServices.action == 2) {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); // initPenguinSDK();
locator<GAnalytics>().hmgServices.logServiceName('emergency service'); if (projectViewModel.isIndoorNavigationEnabled) {
if (!isLocked) openNavigationProjectSelection(context);
} else {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true)));
locator<GAnalytics>().hmgServices.logServiceName('emergency service');
}
} else if (hmgServices.action == 3) { } else if (hmgServices.action == 3) {
Navigator.push(context, FadePage(page: HomeHealthCarePage())); Navigator.push(context, FadePage(page: HomeHealthCarePage()));
locator<GAnalytics>().hmgServices.logServiceName('home health care'); locator<GAnalytics>().hmgServices.logServiceName('home health care');
@ -195,6 +257,9 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 23) { } else if (hmgServices.action == 23) {
Navigator.push(context, FadePage(page: InPatientServicesHome())); Navigator.push(context, FadePage(page: InPatientServicesHome()));
locator<GAnalytics>().hmgServices.logServiceName('find us reach us'); locator<GAnalytics>().hmgServices.logServiceName('find us reach us');
} else if (hmgServices.action == 9) {
Navigator.push(context, FadePage(page: EROnlineCheckInHomePage()));
locator<GAnalytics>().hmgServices.logServiceName('ER Online CheckIn');
} }
} }
@ -266,10 +331,8 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 21) { } else if (hmgServices.action == 21) {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (BuildContext context) => MyWebView( builder: (BuildContext context) => MyWebView(title: "HMG News", selectedUrl: "https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
title: "HMG News", ),
selectedUrl:"https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
),
), ),
); );
locator<GAnalytics>().hmgServices.logServiceName('latest news'); locator<GAnalytics>().hmgServices.logServiceName('latest news');

@ -4,6 +4,8 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.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/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart';
@ -15,6 +17,7 @@ import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.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/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -317,53 +320,87 @@ class _LiveCarePatmentPageState extends State<LiveCarePatmentPage> {
Container( Container(
padding: EdgeInsets.all(12), padding: EdgeInsets.all(12),
color: Colors.white, color: Colors.white,
child: Flex( child: Column(
direction: Axis.horizontal, children: [
children: <Widget>[ Flex(
Expanded( direction: Axis.horizontal,
child: DefaultButton( children: <Widget>[
TranslationBase.of(context).cancel, Expanded(
() { child: DefaultButton(
if (widget.isPharmaLiveCare) cancelAPI(); TranslationBase.of(context).cancel,
Navigator.pop(context, false); () {
}, if (widget.isPharmaLiveCare) cancelAPI();
), Navigator.pop(context, false);
), },
mWidth(12), ),
Expanded( ),
child: DefaultButton( mWidth(12),
TranslationBase.of(context).next, Expanded(
() { child: DefaultButton(
if (_selected == 0) { TranslationBase.of(context).next,
AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); () {
} else { if (_selected == 0) {
if (widget.isPharmaLiveCare) { AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms);
Navigator.pop(context, true); } else {
} else { if (widget.isPharmaLiveCare) {
askVideoCallPermission().then((value) async { Navigator.pop(context, true);
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 { } 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<dynamic> route) => false,
);
Navigator.push(context, FadePage(page: InsuranceUpdate()));
},
color: Color(0xffEAA118),
textColor: Colors.white,
),
],
)
: Container(),
], ],
), ),
), ),

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save