Merge pull request 'haroon_dev' (#188) from haroon_dev into master

Reviewed-on: https://34.17.182.140/Haroon6138/HMG_Patient_App_New/pulls/188
master
Haroon6138 22 hours ago
commit 658b77aa37

@ -0,0 +1 @@
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"2640966000002322881","product_id":"736430079244816567","client_id":"563735388191982656","client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF","project_id":"736430079244816567","app_id":"116912301","api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI","package_name":"com.cloudsolutions.HMGPatientApp"},"oauth_client":{"client_id":"116912301","client_type":1},"app_info":{"app_id":"116912301","package_name":"com.cloudsolutions.HMGPatientApp"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"com.cloudsolutions.HMGPatientApp","client":{"app_id":"116912301"},"app_info":{"package_name":"com.cloudsolutions.HMGPatientApp","app_id":"116912301"},"oauth_client":{"client_type":1,"client_id":"116912301"}},{"package_name":"com.ejada.hmg","client":{"app_id":"102857389"},"app_info":{"package_name":"com.ejada.hmg","app_id":"102857389"},"oauth_client":{"client_type":1,"client_id":"102857389"}}]}

@ -1,74 +1 @@
{
"agcgw":{
"backurl":"connect-drcn.hispace.hicloud.com",
"url":"connect-drcn.dbankcloud.cn",
"websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com",
"websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn"
},
"agcgw_all":{
"CN":"connect-drcn.dbankcloud.cn",
"CN_back":"connect-drcn.hispace.hicloud.com",
"DE":"connect-dre.dbankcloud.cn",
"DE_back":"connect-dre.hispace.hicloud.com",
"RU":"connect-drru.dbankcloud.cn",
"RU_back":"connect-drru.hispace.hicloud.com",
"SG":"connect-dra.dbankcloud.cn",
"SG_back":"connect-dra.hispace.hicloud.com"
},
"client":{
"cp_id":"2640966000002322881",
"product_id":"736430079244816567",
"client_id":"563735388191982656",
"client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF",
"project_id":"736430079244816567",
"app_id":"102857389",
"api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI",
"package_name":"com.ejada.hmg"
},
"oauth_client":{
"client_id":"102857389",
"client_type":1
},
"app_info":{
"app_id":"102857389",
"package_name":"com.ejada.hmg"
},
"service":{
"analytics":{
"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"collector_url_ru":"datacollector-drru.dt.hicloud.com,datacollector-drru.dt.dbankcloud.cn",
"collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
"collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-drcn.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn"
},
"ml":{
"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
}
},
"region":"CN",
"configuration_version":"3.0",
"appInfos":[
{
"package_name":"com.ejada.hmg",
"client":{
"app_id":"102857389"
},
"app_info":{
"package_name":"com.ejada.hmg",
"app_id":"102857389"
},
"oauth_client":{
"client_type":1,
"client_id":"102857389"
}
}
]
}
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"2640966000002322881","product_id":"736430079244816567","client_id":"563735388191982656","client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF","project_id":"736430079244816567","app_id":"116912301","api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI","package_name":"com.cloudsolutions.HMGPatientApp"},"oauth_client":{"client_id":"116912301","client_type":1},"app_info":{"app_id":"116912301","package_name":"com.cloudsolutions.HMGPatientApp"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"com.cloudsolutions.HMGPatientApp","client":{"app_id":"116912301"},"app_info":{"package_name":"com.cloudsolutions.HMGPatientApp","app_id":"116912301"},"oauth_client":{"client_type":1,"client_id":"116912301"}},{"package_name":"com.ejada.hmg","client":{"app_id":"102857389"},"app_info":{"package_name":"com.ejada.hmg","app_id":"102857389"},"oauth_client":{"client_type":1,"client_id":"102857389"}}]}

@ -18,12 +18,14 @@ if (keystorePropertiesFile.exists()) {
}
android {
namespace = "com.ejada.hmg"
// namespace = "com.ejada.hmg"
namespace = "com.cloudsolutions.HMGPatientApp"
compileSdk = 36
ndkVersion = "28.2.13676358"
defaultConfig {
applicationId = "com.ejada.hmg"
// applicationId = "com.ejada.hmg"
applicationId = "com.cloudsolutions.HMGPatientApp"
// minSdk = 24
minSdk = 26
targetSdk = 36

@ -3,9 +3,45 @@
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.appspot.com"
"storage_bucket": "api-project-815750722565.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:fa20b3a2401e08633c186c",
"android_client_info": {
"package_name": "com.cloudsolutions.HMGPatientApp"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
}
],
"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"
}
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063",

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.ejada.hmg">
package="com.cloudsolutions.HMGPatientApp">
<!--
io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
@ -129,21 +129,21 @@
android:name=".Application"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher_local"
android:label="Dr. Alhabib"
android:label="Dr. Alhabib Beta"
android:screenOrientation="sensorPortrait"
android:showOnLockScreen="true"
android:usesCleartextTraffic="true"
tools:replace="android:label">
<activity
android:name="com.cloud.hmg_patient_app.whatsapp.WhatsAppCodeActivity"
android:exported="true"
android:enabled="true"
android:launchMode="standard"
>
<intent-filter>
<action android:name="com.whatsapp.otp.OTP_RETRIEVED" />
</intent-filter>
</activity>
<!-- <activity-->
<!-- android:name="com.cloud.hmg_patient_app.whatsapp.WhatsAppCodeActivity"-->
<!-- android:exported="true"-->
<!-- android:enabled="true"-->
<!-- android:launchMode="standard"-->
<!-- >-->
<!-- <intent-filter>-->
<!-- <action android:name="com.whatsapp.otp.OTP_RETRIEVED" />-->
<!-- </intent-filter>-->
<!-- </activity>-->
<meta-data
android:name="push_kit_auto_init_enabled"
@ -199,10 +199,10 @@
<!-- </intent-filter> -->
<!-- </receiver> -->
<!-- Geofencing -->
<service
android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- <service-->
<!-- android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService"-->
<!-- android:exported="true"-->
<!-- android:permission="android.permission.BIND_JOB_SERVICE" />-->
<!-- <receiver-->
<!-- android:name=".geofence.intent_receivers.GeofenceBroadcastReceiver"-->

@ -1,27 +0,0 @@
//package com.cloud.diplomaticquarterapp
package com.ejada.hmg
import io.flutter.app.FlutterApplication
class Application : FlutterApplication() {
override fun onCreate() {
super.onCreate()
}
}
//import io.flutter.app.FlutterApplication
//import io.flutter.plugin.common.PluginRegistry
//import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
//
//class Application : FlutterApplication(), PluginRegistrantCallback {
// override fun onCreate() {
// super.onCreate()
// FlutterFirebaseMessagingService.setPluginRegistrant(this)
// }
//
// override fun registerWith(registry: PluginRegistry?) {
// FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
// }
//}

@ -1,51 +0,0 @@
package com.ejada.hmg
import android.app.PendingIntent
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import android.view.WindowManager
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi
import com.ejada.hmg.penguin.PenguinInPlatformBridge
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge
this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)
PenguinInPlatformBridge(flutterEngine, this).create()
}
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() {
super.onResume()
}
}

@ -1,61 +0,0 @@
package com.ejada.hmg.penguin
import com.ejada.hmg.MainActivity
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.ejada.hmg.penguin.PenguinView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import com.ejada.hmg.PermissionManager.HostNotificationPermissionManager
import com.ejada.hmg.PermissionManager.HostBgLocationManager
import com.ejada.hmg.PermissionManager.HostGpsStateManager
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")
if (HostNotificationPermissionManager.isNotificationPermissionGranted(mainActivity))
else HostNotificationPermissionManager.requestNotificationPermission(mainActivity)
HostBgLocationManager.requestLocationBackgroundPermission(mainActivity)
HostGpsStateManager.requestLocationPermission(mainActivity)
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()
}
}
}
}
}

@ -1,139 +0,0 @@
package com.ejada.hmg.PermissionManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.HandlerThread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
/**
* This preferences for app level
*/
public class AppPreferences {
public static final String PREF_NAME = "PenguinINUI_AppPreferences";
public static final int MODE = Context.MODE_PRIVATE;
public static final String campusIdKey = "campusId";
public static final String LANG = "Lang";
public static final String settingINFO = "SETTING-INFO";
public static final String userName = "userName";
public static final String passWord = "passWord";
private static HandlerThread handlerThread;
private static Handler handler;
static {
handlerThread = new HandlerThread("PreferencesHandlerThread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
public static SharedPreferences getPreferences(final Context context) {
return context.getSharedPreferences(AppPreferences.PREF_NAME, AppPreferences.MODE);
}
public static SharedPreferences.Editor getEditor(final Context context) {
return getPreferences(context).edit();
}
public static void writeInt(final Context context, final String key, final int value) {
handler.post(() -> {
SharedPreferences.Editor editor = getEditor(context);
editor.putInt(key, value);
editor.apply();
});
}
public static int readInt(final Context context, final String key, final int defValue) {
Callable<Integer> callable = () -> {
SharedPreferences preferences = getPreferences(context);
return preferences.getInt(key, -1);
};
Future<Integer> future = new FutureTask<>(callable);
handler.post((Runnable) future);
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Handle the exception appropriately
}
return -1; // Return the default value in case of an error
}
public static int getCampusId(final Context context) {
return readInt(context,campusIdKey,-1);
}
public static void writeString(final Context context, final String key, final String value) {
handler.post(() -> {
SharedPreferences.Editor editor = getEditor(context);
editor.putString(key, value);
editor.apply();
});
}
public static String readString(final Context context, final String key, final String defValue) {
Callable<String> callable = () -> {
SharedPreferences preferences = getPreferences(context);
return preferences.getString(key, defValue);
};
Future<String> future = new FutureTask<>(callable);
handler.post((Runnable) future);
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Handle the exception appropriately
}
return defValue; // Return the default value in case of an error
}
public static void writeBoolean(final Context context, final String key, final boolean value) {
handler.post(() -> {
SharedPreferences.Editor editor = getEditor(context);
editor.putBoolean(key, value);
editor.apply();
});
}
public static boolean readBoolean(final Context context, final String key, final boolean defValue) {
Callable<Boolean> callable = () -> {
SharedPreferences preferences = getPreferences(context);
return preferences.getBoolean(key, defValue);
};
Future<Boolean> future = new FutureTask<>(callable);
handler.post((Runnable) future);
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Handle the exception appropriately
}
return defValue; // Return the default value in case of an error
}
}

@ -1,136 +0,0 @@
package com.ejada.hmg.PermissionManager;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.peng.pennavmap.PlugAndPlaySDK;
import com.peng.pennavmap.R;
import com.peng.pennavmap.enums.InitializationErrorType;
/**
* Manages background location permission requests and handling for the application.
*/
public class HostBgLocationManager {
/**
* Request code for background location permission
*/
public static final int REQUEST_ACCESS_BACKGROUND_LOCATION_CODE = 301;
/**
* Request code for navigating to app settings
*/
private static final int REQUEST_CODE_SETTINGS = 11234;
/**
* Alert dialog for denied permissions
*/
private static AlertDialog deniedAlertDialog;
/**
* Checks if the background location permission has been granted.
*
* @param context the context of the application or activity
* @return true if the permission is granted, false otherwise
*/
public static boolean isLocationBackgroundGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
== PackageManager.PERMISSION_GRANTED;
}
/**
* Requests the background location permission from the user.
*
* @param activity the activity from which the request is made
*/
public static void requestLocationBackgroundPermission(Activity activity) {
// Check if the ACCESS_BACKGROUND_LOCATION permission is already granted
if (!isLocationBackgroundGranted(activity)) {
// Permission is not granted, so request it
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
REQUEST_ACCESS_BACKGROUND_LOCATION_CODE);
}
}
/**
* Displays a dialog prompting the user to grant the background location permission.
*
* @param activity the activity where the dialog is displayed
*/
public static void showLocationBackgroundPermission(Activity activity) {
AlertDialog alertDialog = new AlertDialog.Builder(activity)
.setCancelable(false)
.setMessage(activity.getString(R.string.com_penguin_nav_ui_geofence_alert_msg))
.setPositiveButton(activity.getString(R.string.com_penguin_nav_ui_go_to_settings), (dialog, which) -> {
if (activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
HostBgLocationManager.requestLocationBackgroundPermission(activity);
} else {
openAppSettings(activity);
}
if (dialog != null) {
dialog.dismiss();
}
})
.setNegativeButton(activity.getString(R.string.com_penguin_nav_ui_later), (dialog, which) -> {
dialog.cancel();
})
.create();
alertDialog.show();
}
/**
* Handles the scenario where permissions are denied by the user.
* Displays a dialog to guide the user to app settings or exit the activity.
*
* @param activity the activity where the dialog is displayed
*/
public static synchronized void handlePermissionsDenied(Activity activity) {
if (deniedAlertDialog != null && deniedAlertDialog.isShowing()) {
deniedAlertDialog.dismiss();
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setCancelable(false)
.setMessage(activity.getString(R.string.com_penguin_nav_ui_permission_denied_dialog_msg))
.setNegativeButton(activity.getString(R.string.com_penguin_nav_ui_cancel), (dialogInterface, i) -> {
if (PlugAndPlaySDK.externalPenNavUIDelegate != null) {
PlugAndPlaySDK.externalPenNavUIDelegate.onPenNavInitializationError(
InitializationErrorType.permissions.getTypeKey(),
InitializationErrorType.permissions);
}
activity.finish();
})
.setPositiveButton(activity.getString(R.string.com_penguin_nav_ui_go_settings), (dialogInterface, i) -> {
dialogInterface.dismiss();
openAppSettings(activity);
});
deniedAlertDialog = builder.create();
deniedAlertDialog.show();
}
/**
* Opens the application's settings screen to allow the user to modify permissions.
*
* @param activity the activity from which the settings screen is launched
*/
private static void openAppSettings(Activity activity) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
if (intent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(intent, REQUEST_CODE_SETTINGS);
}
}
}

@ -1,68 +0,0 @@
package com.ejada.hmg.PermissionManager;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.peng.pennavmap.managers.permissions.managers.BgLocationManager;
public class HostGpsStateManager {
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
public boolean checkGPSEnabled(Activity activity) {
LocationManager gpsStateManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
return gpsStateManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
public static boolean isGpsGranted(Activity activity) {
return BgLocationManager.isLocationBackgroundGranted(activity)
|| ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED;
}
/**
* Checks if the location permission is granted.
*
* @param activity the Activity context
* @return true if permission is granted, false otherwise
*/
public static boolean isLocationPermissionGranted(Activity activity) {
return ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED;
}
/**
* Requests the location permission.
*
* @param activity the Activity context
*/
public static void requestLocationPermission(Activity activity) {
ActivityCompat.requestPermissions(
activity,
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
},
LOCATION_PERMISSION_REQUEST_CODE
);
}
}

@ -1,73 +0,0 @@
package com.ejada.hmg.PermissionManager;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationManagerCompat;
public class HostNotificationPermissionManager {
private static final int REQUEST_NOTIFICATION_PERMISSION = 100;
/**
* Checks if the notification permission is granted.
*
* @return true if the notification permission is granted, false otherwise.
*/
public static boolean isNotificationPermissionGranted(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
try {
return ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED;
} catch (Exception e) {
// Handle cases where the API is unavailable
e.printStackTrace();
return NotificationManagerCompat.from(activity).areNotificationsEnabled();
}
} else {
// Permissions were not required below Android 13 for notifications
return NotificationManagerCompat.from(activity).areNotificationsEnabled();
}
}
/**
* Requests the notification permission.
*/
public static void requestNotificationPermission(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (!isNotificationPermissionGranted(activity)) {
ActivityCompat.requestPermissions(activity,
new String[]{android.Manifest.permission.POST_NOTIFICATIONS},
REQUEST_NOTIFICATION_PERMISSION);
}
}
}
/**
* Handles the result of the permission request.
*
* @param requestCode The request code passed in requestPermissions().
* @param permissions The requested permissions.
* @param grantResults The grant results for the corresponding permissions.
*/
public static boolean handlePermissionResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (permissions.length > 0 &&
permissions[0].equals(android.Manifest.permission.POST_NOTIFICATIONS) &&
grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
System.out.println("Notification permission granted.");
return true;
} else {
// Permission denied
System.out.println("Notification permission denied.");
return false;
}
}
}

@ -1,28 +0,0 @@
package com.ejada.hmg.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()
}
}

@ -1,50 +0,0 @@
package com.ejada.hmg.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()
}
}
}
}

@ -1,15 +0,0 @@
package com.ejada.hmg.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)
}
}

@ -1,13 +0,0 @@
package com.ejada.hmg.penguin
enum class PenguinMethod {
// initializePenguin("initializePenguin"),
// configurePenguin("configurePenguin"),
// showPenguinUI("showPenguinUI"),
// onPenNavUIDismiss("onPenNavUIDismiss"),
// onReportIssue("onReportIssue"),
// onPenNavSuccess("onPenNavSuccess"),
onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"),
// navigateToPOI("navigateToPOI"),
// openSharedLocation("openSharedLocation");
}

@ -1,97 +0,0 @@
package com.ejada.hmg.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+++++++ $refID")
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")
}
}
}

@ -1,377 +0,0 @@
package com.ejada.hmg.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.ejada.hmg.PermissionManager.PermissionManager
import com.ejada.hmg.PermissionManager.PermissionResultReceiver
import com.ejada.hmg.MainActivity
import com.ejada.hmg.PermissionManager.PermissionHelper
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.ejada.hmg.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.LocationMessage
import com.peng.pennavmap.models.PIReportIssue
import java.util.ArrayList
import penguin.com.pennav.renderer.PIRendererSettings
/**
* 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, PIEventsDelegate,
PILocationDelegate {
// 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().get(0)
)
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
}
}
// PlugAndPlaySDK.configuration = Builder()
// .setClientData(MConstantsDemo.CLIENT_ID, MConstantsDemo.CLIENT_KEY)
// .setLanguageID(selectedLanguage)
// .setBaseUrl(MConstantsDemo.DATA_URL, MConstantsDemo.POSITION_URL)
// .setServiceName(MConstantsDemo.DATA_SERVICE_NAME, MConstantsDemo.POSITION_SERVICE_NAME)
// .setUserName(name)
// .setSimulationModeEnabled(isSimulation)
// .setCustomizeColor(if (MConstantsDemo.APP_COLOR != null) MConstantsDemo.APP_COLOR else "#2CA0AF")
// .setEnableBackButton(MConstantsDemo.SHOW_BACK_BUTTON)
// .setCampusId(MConstantsDemo.selectedCampusId)
//
// .setShowUILoader(true)
// .build()
PIRendererSettings.styleUri = "mapbox://styles/rwaid/cm3h30b36007v01qz7ik8a0sk"
PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder()
.setBaseUrl(
creationParams["dataURL"] as String,
creationParams["positionURL"] as String
)
.setServiceName(
creationParams["dataServiceName"] as String,
creationParams["positionServiceName"] as String
)
.setClientData(
creationParams["clientID"] as String,
creationParams["clientKey"] as String
)
.setUserName(creationParams["username"] as String)
// .setLanguageID(Languages.en)
.setLanguageID(language)
.setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean)
.setEnableBackButton(true)
// .setDeepLinkData("deeplink")
.setCustomizeColor("#2CA0AF")
.setDeepLinkSchema("", "")
.setIsEnableReportIssue(true)
.setDeepLinkData("")
.setEnableSharedLocationCallBack(false)
.setShowUILoader(true)
.setCampusId(creationParams["projectID"] as Int)
.build()
Log.d(
"TAG",
"initPenguin: ${creationParams["projectID"]}"
)
Log.d(
"TAG",
"initPenguin: creation param are ${creationParams}"
)
// Set location delegate to handle location updates
// PlugAndPlaySDK.setPiLocationDelegate {
// Example code to handle location updates
// Uncomment and modify as needed
// if (location.size() > 0)
// Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show()
// }
// Set events delegate for reporting issues
// PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() {
// @Override
// public void onReportIssue(PIReportIssue issue) {
// Log.e("Issue Reported: ", issue.getReportType());
// }
// // Implement issue reporting logic here }
// @Override
// public void onSharedLocation(String link) {
// // Implement Shared location logic here
// }
// })
// Start the Penguin SDK
PlugAndPlaySDK.setPiEventsDelegate(this)
PlugAndPlaySDK.setPiLocationDelegate(this)
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)
// navigateTo("3-1")
}
/**
* 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
)
Log.d(
"description",
"description : ${description}"
)
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")
}
}
override fun onReportIssue(issue: PIReportIssue?) {
TODO("Not yet implemented")
}
override fun onSharedLocation(link: String?) {
TODO("Not yet implemented")
}
override fun onLocationOffCampus(location: ArrayList<Double>?) {
TODO("Not yet implemented")
}
override fun onLocationMessage(locationMessage: LocationMessage?) {
TODO("Not yet implemented")
}
}

@ -3,9 +3,45 @@
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.appspot.com"
"storage_bucket": "api-project-815750722565.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:fa20b3a2401e08633c186c",
"android_client_info": {
"package_name": "com.cloudsolutions.HMGPatientApp"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
}
],
"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"
}
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063",

@ -19,6 +19,9 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
// id("com.android.application") version "8.9.3" apply false
// START: FlutterFire Configuration
id("com.google.gms.google-services") version("4.4.1") apply false
// END: FlutterFire Configuration
id("com.android.application") version "8.9.3" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
}

@ -1,767 +1 @@
{
"nm": "HDFC Success",
"h": 512,
"w": 512,
"meta": {
"g": "LottieFiles AE 1.0.0"
},
"layers": [
{
"ty": 4,
"nm": "check",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
256,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Shape 1",
"it": [
{
"ty": "sh",
"nm": "Path 1",
"d": 1,
"ks": {
"a": 0,
"k": {
"c": false,
"i": [
[
0,
0
],
[
0,
0
],
[
0,
0
]
],
"o": [
[
0,
0
],
[
0,
0
],
[
0,
0
]
],
"v": [
[
-82.5,
4.5
],
[
-31,
55
],
[
73,
-52.5
]
]
}
}
},
{
"ty": "tm",
"nm": "Trim Paths 1",
"e": {
"a": 1,
"k": [
{
"o": {
"x": 1,
"y": 0.076
},
"i": {
"x": 0.667,
"y": 1
},
"s": [
0
],
"t": 60
},
{
"s": [
100
],
"t": 85
}
]
},
"o": {
"a": 0,
"k": 0
},
"s": {
"a": 0,
"k": 0
},
"m": 1
},
{
"ty": "st",
"nm": "Stroke 1",
"lc": 2,
"lj": 2,
"ml": 1,
"o": {
"a": 0,
"k": 100
},
"w": {
"a": 0,
"k": 30
},
"c": {
"a": 0,
"k": [
1,
1,
1
]
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 1
},
{
"ty": 4,
"nm": "Shape Layer 2",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 1,
"k": [
{
"o": {
"x": 0.656,
"y": 0.872
},
"i": {
"x": 0,
"y": 0.98
},
"s": [
0,
0,
100
],
"t": 20
},
{
"s": [
150,
150,
100
],
"t": 60
}
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
257.86,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Ellipse 1",
"it": [
{
"ty": "el",
"nm": "Ellipse Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
236,
236
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.094,
0.761,
0.451
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
-3
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 2
},
{
"ty": 4,
"nm": "Shape Layer 1",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 1,
"k": [
{
"o": {
"x": 0.477,
"y": 0.587
},
"i": {
"x": 0,
"y": 0.999
},
"s": [
0,
0,
100
],
"t": 10
},
{
"o": {
"x": 0.167,
"y": 0.167
},
"i": {
"x": 0.833,
"y": 0.833
},
"s": [
150,
150,
100
],
"t": 50
},
{
"o": {
"x": 0.167,
"y": 0
},
"i": {
"x": 0.833,
"y": 1
},
"s": [
150,
150,
100
],
"t": 76
},
{
"s": [
210,
210,
100
],
"t": 123
}
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
257.86,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 1,
"k": [
{
"o": {
"x": 0.912,
"y": 0.073
},
"i": {
"x": 0.626,
"y": 0.729
},
"s": [
100
],
"t": 76
},
{
"s": [
0
],
"t": 119
}
]
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Ellipse 1",
"it": [
{
"ty": "el",
"nm": "Ellipse Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
236,
236
]
}
},
{
"ty": "st",
"nm": "Stroke 1",
"lc": 1,
"lj": 1,
"ml": 4,
"o": {
"a": 0,
"k": 100
},
"w": {
"a": 0,
"k": 2
},
"c": {
"a": 0,
"k": [
1,
1,
1
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.784,
0.945,
0.878
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
-3
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 3
},
{
"ty": 4,
"nm": "BG",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
256,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Rectangle 1",
"it": [
{
"ty": "rc",
"nm": "Rectangle Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"r": {
"a": 0,
"k": 0
},
"s": {
"a": 0,
"k": [
554,
556
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.972,
0.972,
0.972
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
-1,
6
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 4
}
],
"v": "4.8.0",
"fr": 60,
"op": 130,
"ip": 0,
"assets": []
}
{"nm":"Main Scene","ddd":0,"h":512,"w":512,"meta":{"g":"@lottiefiles/creator 1.75.0"},"layers":[{"ty":4,"nm":"check","sr":1,"st":0,"op":240,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256,256],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-82.5,4.5],[-31,55],[73,-52.5]]},"ix":2}},{"ty":"tm","bm":0,"hd":false,"mn":"ADBE Vector Filter - Trim","nm":"Trim Paths 1","ix":2,"e":{"a":1,"k":[{"o":{"x":1,"y":0.076},"i":{"x":0.667,"y":1},"s":[0],"t":60},{"s":[100],"t":85}],"ix":2},"o":{"a":0,"k":0,"ix":3},"s":{"a":0,"k":0,"ix":1},"m":1},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":2,"ml":1,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":240,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.656,"y":0.872},"i":{"x":0,"y":0.98},"s":[0,0,100],"t":20},{"s":[150,150,100],"t":60}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256,257.86],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[236,236],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0941,0.7608,0.451],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,-3],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2},{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":240,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.477,"y":0.587},"i":{"x":0,"y":0.999},"s":[0,0,100],"t":10},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[150,150,100],"t":50},{"o":{"x":0.167,"y":0},"i":{"x":0.833,"y":1},"s":[150,150,100],"t":76},{"s":[210,210,100],"t":123}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256,257.86],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.912,"y":0.073},"i":{"x":0.626,"y":0.729},"s":[100],"t":76},{"s":[0],"t":119}],"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[236,236],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7843,0.9451,0.8784],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,-3],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3}],"v":"5.7.0","fr":60,"op":130,"ip":0,"assets":[]}

@ -0,0 +1,767 @@
{
"nm": "HDFC Success",
"h": 512,
"w": 512,
"meta": {
"g": "LottieFiles AE 1.0.0"
},
"layers": [
{
"ty": 4,
"nm": "check",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
256,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Shape 1",
"it": [
{
"ty": "sh",
"nm": "Path 1",
"d": 1,
"ks": {
"a": 0,
"k": {
"c": false,
"i": [
[
0,
0
],
[
0,
0
],
[
0,
0
]
],
"o": [
[
0,
0
],
[
0,
0
],
[
0,
0
]
],
"v": [
[
-82.5,
4.5
],
[
-31,
55
],
[
73,
-52.5
]
]
}
}
},
{
"ty": "tm",
"nm": "Trim Paths 1",
"e": {
"a": 1,
"k": [
{
"o": {
"x": 1,
"y": 0.076
},
"i": {
"x": 0.667,
"y": 1
},
"s": [
0
],
"t": 60
},
{
"s": [
100
],
"t": 85
}
]
},
"o": {
"a": 0,
"k": 0
},
"s": {
"a": 0,
"k": 0
},
"m": 1
},
{
"ty": "st",
"nm": "Stroke 1",
"lc": 2,
"lj": 2,
"ml": 1,
"o": {
"a": 0,
"k": 100
},
"w": {
"a": 0,
"k": 30
},
"c": {
"a": 0,
"k": [
1,
1,
1
]
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 1
},
{
"ty": 4,
"nm": "Shape Layer 2",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 1,
"k": [
{
"o": {
"x": 0.656,
"y": 0.872
},
"i": {
"x": 0,
"y": 0.98
},
"s": [
0,
0,
100
],
"t": 20
},
{
"s": [
150,
150,
100
],
"t": 60
}
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
257.86,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Ellipse 1",
"it": [
{
"ty": "el",
"nm": "Ellipse Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
236,
236
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.094,
0.761,
0.451
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
-3
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 2
},
{
"ty": 4,
"nm": "Shape Layer 1",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 1,
"k": [
{
"o": {
"x": 0.477,
"y": 0.587
},
"i": {
"x": 0,
"y": 0.999
},
"s": [
0,
0,
100
],
"t": 10
},
{
"o": {
"x": 0.167,
"y": 0.167
},
"i": {
"x": 0.833,
"y": 0.833
},
"s": [
150,
150,
100
],
"t": 50
},
{
"o": {
"x": 0.167,
"y": 0
},
"i": {
"x": 0.833,
"y": 1
},
"s": [
150,
150,
100
],
"t": 76
},
{
"s": [
210,
210,
100
],
"t": 123
}
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
257.86,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 1,
"k": [
{
"o": {
"x": 0.912,
"y": 0.073
},
"i": {
"x": 0.626,
"y": 0.729
},
"s": [
100
],
"t": 76
},
{
"s": [
0
],
"t": 119
}
]
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Ellipse 1",
"it": [
{
"ty": "el",
"nm": "Ellipse Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
236,
236
]
}
},
{
"ty": "st",
"nm": "Stroke 1",
"lc": 1,
"lj": 1,
"ml": 4,
"o": {
"a": 0,
"k": 100
},
"w": {
"a": 0,
"k": 2
},
"c": {
"a": 0,
"k": [
1,
1,
1
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.784,
0.945,
0.878
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
0,
-3
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 3
},
{
"ty": 4,
"nm": "BG",
"sr": 1,
"st": 0,
"op": 240,
"ip": 0,
"hasMask": false,
"ao": 0,
"ks": {
"a": {
"a": 0,
"k": [
0,
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
256,
256,
0
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
},
"ef": [],
"shapes": [
{
"ty": "gr",
"nm": "Rectangle 1",
"it": [
{
"ty": "rc",
"nm": "Rectangle Path 1",
"d": 1,
"p": {
"a": 0,
"k": [
0,
0
]
},
"r": {
"a": 0,
"k": 0
},
"s": {
"a": 0,
"k": [
554,
556
]
}
},
{
"ty": "fl",
"nm": "Fill 1",
"c": {
"a": 0,
"k": [
0.972,
0.972,
0.972
]
},
"r": 1,
"o": {
"a": 0,
"k": 100
}
},
{
"ty": "tr",
"a": {
"a": 0,
"k": [
0,
0
]
},
"s": {
"a": 0,
"k": [
100,
100
]
},
"sk": {
"a": 0,
"k": 0
},
"p": {
"a": 0,
"k": [
-1,
6
]
},
"r": {
"a": 0,
"k": 0
},
"sa": {
"a": 0,
"k": 0
},
"o": {
"a": 0,
"k": 100
}
}
]
}
],
"ind": 4
}
],
"v": "4.8.0",
"fr": 60,
"op": 130,
"ip": 0,
"assets": []
}

@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" rx="8" fill="#EFEFF0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.312 9.93059C23.9686 9.74998 22.2479 9.74999 20.0572 9.75H19.9428C17.7521 9.74999 16.0314 9.74998 14.688 9.93059C13.3114 10.1157 12.2191 10.5027 11.3609 11.3609C10.5027 12.2191 10.1157 13.3114 9.93059 14.688C9.74998 16.0314 9.74999 17.7521 9.75 19.9428V20.0572C9.74999 22.2479 9.74998 23.9686 9.93059 25.312C10.1157 26.6886 10.5027 27.7809 11.3609 28.6391C12.2191 29.4973 13.3114 29.8843 14.688 30.0694C16.0314 30.25 17.7521 30.25 19.9428 30.25H19.9428H20.0572H20.0572C22.2479 30.25 23.9686 30.25 25.312 30.0694C26.6886 29.8843 27.7809 29.4973 28.6391 28.6391C29.4973 27.7809 29.8843 26.6886 30.0694 25.312C30.25 23.9686 30.25 22.2479 30.25 20.0572V20.0572V19.9428V19.9428C30.25 17.7521 30.25 16.0314 30.0694 14.688C29.8843 13.3114 29.4973 12.2191 28.6391 11.3609C27.7809 10.5027 26.6886 10.1157 25.312 9.93059ZM20.75 16C20.75 15.5858 20.4142 15.25 20 15.25C19.5858 15.25 19.25 15.5858 19.25 16L19.25 24C19.25 24.4142 19.5858 24.75 20 24.75C20.4142 24.75 20.75 24.4142 20.75 24L20.75 16ZM17.75 18C17.75 17.5858 17.4142 17.25 17 17.25C16.5858 17.25 16.25 17.5858 16.25 18L16.25 22C16.25 22.4142 16.5858 22.75 17 22.75C17.4142 22.75 17.75 22.4142 17.75 22L17.75 18ZM23.75 18C23.75 17.5858 23.4142 17.25 23 17.25C22.5858 17.25 22.25 17.5858 22.25 18L22.25 22C22.25 22.4142 22.5858 22.75 23 22.75C23.4142 22.75 23.75 22.4142 23.75 22L23.75 18ZM14.75 19C14.75 18.5858 14.4142 18.25 14 18.25C13.5858 18.25 13.25 18.5858 13.25 19L13.25 21C13.25 21.4142 13.5858 21.75 14 21.75C14.4142 21.75 14.75 21.4142 14.75 21V19ZM26.75 19C26.75 18.5858 26.4142 18.25 26 18.25C25.5858 18.25 25.25 18.5858 25.25 19L25.25 21C25.25 21.4142 25.5858 21.75 26 21.75C26.4142 21.75 26.75 21.4142 26.75 21V19Z" fill="#2E3039"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" rx="8" fill="#EFEFF0"/>
<path d="M13.3173 9.28657C13.8839 9.40369 14.3352 9.78443 14.6156 10.2875L15.5088 11.8899C15.8379 12.4801 16.1147 12.9768 16.2955 13.4086C16.4873 13.8666 16.6013 14.3182 16.5492 14.8176C16.4971 15.317 16.2925 15.7354 16.0103 16.144C15.7443 16.5292 15.3709 16.958 14.9272 17.4677L13.6142 18.9759C13.3789 19.2461 13.2612 19.3812 13.2505 19.5501C13.2397 19.719 13.3362 19.8633 13.529 20.1518C15.1726 22.6109 17.3877 24.8268 19.8488 26.4718C20.1374 26.6647 20.2816 26.7611 20.4505 26.7503C20.6194 26.7396 20.7546 26.6219 21.0248 26.3866L22.5331 25.0736C23.0427 24.6299 23.4716 24.2565 23.8568 23.9905C24.2653 23.7083 24.6838 23.5036 25.1831 23.4516C25.6825 23.3995 26.1342 23.5134 26.5922 23.7052C27.0239 23.886 27.5206 24.1629 28.1107 24.4918L29.7133 25.3851C30.2163 25.6655 30.5971 26.1168 30.7142 26.6835C30.8325 27.2561 30.658 27.8316 30.2724 28.3047C28.8735 30.021 26.6322 31.1139 24.281 30.6396C22.8358 30.348 21.4098 29.8623 19.6851 28.8732C16.2197 26.8858 13.1126 23.777 11.1276 20.3157C10.1384 18.591 9.65272 17.165 9.36118 15.7197C8.88688 13.3685 9.97971 11.1272 11.6961 9.72833C12.1691 9.34279 12.7447 9.16822 13.3173 9.28657Z" fill="#2E3039"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" rx="8" fill="#EFEFF0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.072 11H16.928C15.3393 11 14.0461 10.9999 13.0263 11.1371C11.9623 11.2801 11.0474 11.5887 10.318 12.318C9.58869 13.0474 9.28011 13.9623 9.13706 15.0263C8.99995 16.0461 8.99997 17.3393 9 18.9279V21.072C8.99997 22.6607 8.99995 23.9539 9.13706 24.9737C9.28011 26.0377 9.58869 26.9527 10.318 27.682C11.0474 28.4113 11.9623 28.7199 13.0263 28.8629C14.0462 29.0001 15.3393 29 16.928 29H18.072C19.6607 29 20.9538 29.0001 21.9737 28.8629C23.0377 28.7199 23.9527 28.4113 24.682 27.682C25.3875 26.9764 25.6993 26.0972 25.8484 25.0773C26.3063 25.4374 26.7206 25.7408 27.0944 25.9666C27.7947 26.3896 28.6822 26.7439 29.5929 26.2925C30.4895 25.848 30.7673 24.9371 30.8829 24.1198C30.9991 23.2982 30.9991 22.1926 30.999 20.8645V19.1382C30.9991 17.8101 30.9991 16.7045 30.8829 15.8828C30.7673 15.0655 30.4895 14.1546 29.5929 13.7102C28.6822 13.2587 27.7947 13.613 27.0944 14.0361C26.7207 14.2619 26.3066 14.5651 25.8488 14.925C25.6998 13.9042 25.3881 13.0241 24.682 12.318C23.9527 11.5887 23.0377 11.2801 21.9737 11.1371C20.9539 10.9999 19.6607 11 18.072 11ZM25.9943 17.3825C26 17.8628 26 18.3777 26 18.928V21.072C26 21.6233 26 22.1391 25.9943 22.6201C26.9515 23.4089 27.6126 23.943 28.1285 24.2547C28.3999 24.4186 28.5637 24.4778 28.6531 24.4955C28.6728 24.4994 28.6863 24.5007 28.6942 24.5012C28.6982 24.5014 28.7027 24.5013 28.7027 24.5013L28.7047 24.5005C28.7064 24.4997 28.7078 24.4988 28.7087 24.4982C28.7101 24.4972 28.7108 24.4966 28.7108 24.4966C28.7136 24.4936 28.7286 24.4774 28.7499 24.4358C28.7977 24.3422 28.8567 24.1641 28.9026 23.8397C28.9966 23.1754 28.999 22.2135 28.999 20.7832V19.2194C28.999 17.7892 28.9966 16.8273 28.9026 16.1629C28.8567 15.8385 28.7977 15.6604 28.7499 15.5669C28.7286 15.5252 28.714 15.5095 28.7112 15.5065C28.7112 15.5065 28.709 15.5043 28.7047 15.5021L28.7032 15.5014C28.7032 15.5014 28.6982 15.5013 28.6942 15.5015C28.6863 15.5019 28.6728 15.5032 28.6531 15.5071C28.5637 15.5248 28.3999 15.584 28.1285 15.748C27.6126 16.0597 26.9515 16.5938 25.9943 17.3825ZM18 16C18 15.4477 18.4477 15 19 15L21 15C21.5523 15 22 15.4477 22 16C22 16.5523 21.5523 17 21 17L19 17C18.4477 17 18 16.5523 18 16Z" fill="#2E3039"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@ -945,6 +945,7 @@
"offline": "غير متصل",
"videoCall": "مكالمة فيديو",
"liveVideoCallWithHMGDoctors": "مكالمة فيديو مباشرة مع أطباء مجموعة الحبيب الطبية",
"liveAudioCallWithHMGDoctors": "مكالمة صوتية مباشرة مع أطباء مجموعة الحبيب الطبية",
"audioCall": "مكالمة صوتية",
"phoneCall": "مكالمة هاتفية",
"livePhoneCallWithHMGDoctors": "مكالمة هاتفية مباشرة مع أطباء مجموعة الحبيب الطبية",
@ -1571,5 +1572,14 @@
"noFreeSlot": "لا توجد مواعيد متاحة في التاريخ المحدد. يرجى اختيار تاريخ آخر أو إعادة المحاولة لاحقاً.",
"noThanksIKnowTheClinic": "لا، شكراً. أنا أعرف العيادة.",
"unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة",
"loadingAIAnalysis": "جارٍ تحميل بياناتك وتحليلها، يُرجى التحلي بالصبر ودع الذكاء الاصطناعي يقوم بالمهمة. يُرجى التحلي بالصبر، فقد يستغرق هذا بعض الوقت."
"loadingAIAnalysis": "جارٍ تحليل نتائج المختبر، يرجى التحلي بالصبر والسماح للذكاء الاصطناعي بالقيام بالمهمة، قد يستغرق هذا بعض الوقت.",
"symptoms": "أعراض",
"insuranceInActive": "التأمين غير نشط",
"insuranceInActiveContactSupport": "لديك تأمين ساري المفعول، ولكنه غير مُفعّل حاليًا في مجموعة حبيب الطبية. يُرجى التواصل مع خدمة عملاء مجموعة حبيب الطبية.",
"updateAppNow": "تحديث التطبيق الآن",
"Dr": "الدكتور.",
"reschedulingAppo": "إعادة جدولة الموعد، يرجى الانتظار...",
"invalidEligibility": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة.",
"invalidInsurance": "لا يمكنك إجراء الدفع عبر الإنترنت لأنه ليس لديك تأمين صالح.",
"continueCash": "تواصل نقدا"
}

@ -937,6 +937,7 @@
"offline": "Offline",
"videoCall": "Video Call",
"liveVideoCallWithHMGDoctors": "Live Video Call with HMG Doctors",
"liveAudioCallWithHMGDoctors": "Live Audio Call with HMG Doctors",
"audioCall": "Audio Call",
"phoneCall": "Phone Call",
"livePhoneCallWithHMGDoctors": "Live Phone Call with HMG Doctors",
@ -1562,5 +1563,14 @@
"contextDependent": "Context Dependent",
"calculatedValue": "Calculated Value",
"calculationFormula": "Calculation Formula",
"loadingAIAnalysis": "Loading and analysing your data, Please be patient and let the AI do the magic. Please be patient, This might take some time."
"loadingAIAnalysis": "Analysing your lab results, Please be patient and let the AI do the magic, This might take some time.",
"symptoms": "Symptoms",
"insuranceInActive": "Insurance Inactive",
"insuranceInActiveContactSupport": "You have a valid insurance but it is currently inactive in HMG. Please contact HMG customer support to activate it.",
"updateAppNow": "Update App Now",
"Dr": "Dr.",
"reschedulingAppo": "Rescheduling Appointment, Please wait...",
"invalidEligibility": "You cannot make online payment because you are not eligible to use the provided service.",
"invalidInsurance": "You cannot make online payment because you do not have a valid insurance.",
"continueCash": "Continue as cash"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"api-project-815750722565","appId":"1:815750722565:android:62281cd3e5df4063","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"api-project-815750722565","appId":"1:815750722565:ios:34ec03c09e02e21f3c186c","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"api-project-815750722565","configurations":{"android":"1:815750722565:android:62281cd3e5df4063","ios":"1:815750722565:ios:34ec03c09e02e21f3c186c"}}}}}}

@ -0,0 +1,83 @@
{
"project_info": {
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:fa20b3a2401e08633c186c",
"android_client_info": {
"package_name": "com.cloudsolutions.HMGPatientApp"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
}
],
"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"
}
}
]
}
}
},
{
"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": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
}
],
"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"
}

@ -24,6 +24,8 @@
765A5A8F2F35CD8B0003FF7D /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
765A5A902F35CD8B0003FF7D /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */; };
765A5A912F35CD8B0003FF7D /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
76AA18AE2F3B2A4D00DC8DFC /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */; };
76AA18AF2F3B2A4D00DC8DFC /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 76AA18AD2F3B2A4D00DC8DFC /* ring_30Sec.mp3 */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -77,6 +79,8 @@
765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenguinINRenderer.xcframework; sourceTree = "<group>"; };
765A5A822F35CD730003FF7D /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenNavUI.xcframework; sourceTree = "<group>"; };
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = "<group>"; };
76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ring_30Sec.caf; sourceTree = "<group>"; };
76AA18AD2F3B2A4D00DC8DFC /* ring_30Sec.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = ring_30Sec.mp3; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8E12CEEB8E334EE22D5259D7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
@ -189,6 +193,8 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */,
76AA18AD2F3B2A4D00DC8DFC /* ring_30Sec.mp3 */,
61243B412EC5FA3700D46FA0 /* Helper */,
61243B472EC5FA3700D46FA0 /* Penguin */,
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */,
@ -300,6 +306,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
76AA18AE2F3B2A4D00DC8DFC /* ring_30Sec.caf in Resources */,
76AA18AF2F3B2A4D00DC8DFC /* ring_30Sec.mp3 in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
478CFA942E638C8E0064F3D7 /* GoogleService-Info.plist in Resources */,
@ -515,7 +523,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -701,7 +709,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -730,7 +738,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;

@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt</string>
<key>ANDROID_CLIENT_ID</key>
<string>815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com</string>
<key>API_KEY</key>
@ -15,24 +11,24 @@
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.HMG.HMG-Smartphone</string>
<string>com.cloudsolutions.HMGPatientApp</string>
<key>PROJECT_ID</key>
<string>api-project-815750722565</string>
<key>STORAGE_BUCKET</key>
<string>api-project-815750722565.appspot.com</string>
<string>api-project-815750722565.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false/>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false/>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true/>
<true></true>
<key>IS_GCM_ENABLED</key>
<true/>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true/>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:815750722565:ios:328ec247a81a2ca23c186c</string>
<string>1:815750722565:ios:34ec03c09e02e21f3c186c</string>
<key>DATABASE_URL</key>
<string>https://api-project-815750722565.firebaseio.com</string>
</dict>
</plist>
</plist>

Binary file not shown.

Binary file not shown.

@ -7,9 +7,11 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/presentation/home/app_update_page.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:http/http.dart' as http;
import '../exceptions/api_failure.dart';
@ -36,6 +38,7 @@ abstract class ApiClient {
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams,
Map<String, String> apiHeaders,
bool isAllowAny,
bool isExternal,
bool isRCService,
@ -192,10 +195,14 @@ class ApiClientImp implements ApiClient {
}
// body['TokenID'] = "@dm!n";
// body['PatientID'] = 4768663;
// body['PatientID'] = 4773715;
// body['PatientTypeID'] = 1;
// body['PatientOutSA'] = 0;
// body['SessionID'] = "45786230487560q";
// body['IdentificationNo'] = "2235558844";
// body['MobileNo'] = "966533147722";
// body['PatientID'] = 809289;
}
if(!url.contains("/paymentApi")) {
@ -220,7 +227,8 @@ class ApiClientImp implements ApiClient {
// Handle body encoding based on isBodyPlainText flag
final dynamic requestBody = isBodyPlainText ? body : json.encode(body);
debugPrint("uri: ${Uri.parse(url.trim())}");
debugPrint("body: ${json.encode(body)}", wrapWidth: 2048);
var requestBodyJSON = json.encode(body);
debugPrint("body: $requestBodyJSON", wrapWidth: 2048);
final response = await http.post(Uri.parse(url.trim()), body: requestBody, headers: headers);
final int statusCode = response.statusCode;
// log("response.body: ${response.body}");
@ -245,8 +253,16 @@ class ApiClientImp implements ApiClient {
} else {
if (parsed['ErrorType'] == 4) {
//TODO : handle app update
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode,
failureType: AppUpdateFailure("parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']"));
// onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode,
// failureType: AppUpdateFailure("parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']"));
ApiClient._navigationService.pushAndRemoveUntil(
CustomPageRoute(
page: AppUpdatePage(
appUpdateMessage: parsed['ErrorEndUserMessage'],
)),
ModalRoute.withName("/appUpdate")
);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
if (parsed['ErrorType'] == 2) {
@ -366,6 +382,7 @@ class ApiClientImp implements ApiClient {
{required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? apiHeaders,
bool isAllowAny = false,
bool isExternal = false,
bool isRCService = false}) async {
@ -390,7 +407,7 @@ class ApiClientImp implements ApiClient {
if (await Utils.checkConnection(bypassConnectionCheck: true)) {
final response = await http.get(
Uri.parse(url.trim()),
headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
headers: apiHeaders ?? {'Content-Type': 'application/json', 'Accept': 'application/json'},
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");

@ -1,6 +1,242 @@
import 'package:amazon_payfort/amazon_payfort.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
static String baseUrl = 'https://hmgwebservices.com/'; // HIS API URL PROD
static String rcBaseUrl = 'https://rc.hmg.com/'; // dRC API URL PROD
static String hmgPharmacyApiBaseUrl = 'https://hmgpharmacyapi.hmg.com/'; // dRC API URL PROD
static String symptomsCheckerApi = '${hmgPharmacyApiBaseUrl}symptomsapi/api/SymptomChecker'; // dRC API URL PROD
static var payFortEnvironment = FortEnvironment.production;
static var applePayMerchantId = "merchant.com.hmgwebservices";
static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE
// static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT
static String TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
static String GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
static String GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
static String QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
static String CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId=";
// static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
// var payFortEnvironment = FortEnvironment.test;
// var applePayMerchantId = "merchant.com.hmgwebservices.uat";
static setBackendURLs() {
switch (appEnvironmentType) {
case AppEnvironmentTypeEnum.prod:
baseUrl = "https://hmgwebservices.com/";
payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices";
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId=";
break;
case AppEnvironmentTypeEnum.dev:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/";
payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices";
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.qa:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
}
}
static final String selectDeviceImei = 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI';
static final String checkPatientAuth = 'Services/Authentication.svc/REST/CheckPatientAuthentication';
static final String sendActivationCode = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType';
static final String sendActivationCodeRegister = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration';
static final String checkActivationCode = 'Services/Authentication.svc/REST/CheckActivationCode';
static final String checkActivationCodeRegister = 'Services/Authentication.svc/REST/CheckActivationCodeForRegistration';
static final String checkUsageAgreement = 'Services/Patients.svc/REST/CheckForUsageAgreement';
static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText';
static final String checkPatientForRegistration = 'Services/Authentication.svc/REST/CheckPatientForRegisteration';
static final String checkUserStatus = 'Services/NHIC.svc/REST/GetPatientInfo';
static final String insertPatientDeviceIMEIData = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI';
static final String insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo';
static final String getPatientMobileData = '/Services/Authentication.svc/REST/GetMobileLoginInfo';
static final String getPrivileges = 'Services/Patients.svc/REST/Service_Privilege';
static final String registerUser = 'Services/Authentication.svc/REST/PatientRegistration';
static final String addFamilyFile = 'Services/Patients.svc/REST/ShareFamilyFileService';
static final String sendFamilyFileActivation = 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile';
static final String checkActivationCodeForFamily = 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile';
static final String getAllPendingRecordsByResponseId = 'Services/Authentication.svc/REST/GetAllPendingRecordsByResponseId';
static final String getAllSharedRecordsByStatus = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus';
static final String removeFileFromFamilyMembers = 'Services/Authentication.svc/REST/ActiveDeactive_PatientFile';
static final String acceptAndRejectFamilyFile = 'Services/Authentication.svc/REST/Update_FileStatus';
static final String getActivePrescriptionsDetails = 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID';
static final String getTermsConditions = 'Services/Patients.svc/Rest/GetUserTermsAndConditions';
static final String getMonthlyReports = 'Services/Patients.svc/Rest/UpdatePateintHealthSummaryReport';
static final String updatePatientEmail = 'Services/Patients.svc/Rest/UpdatePateintEmail';
static final String getQrParkingDetails = 'Services/SWP.svc/REST/GetQRParkingByID';
// Ancillary Order Apis
static final String getOnlineAncillaryOrderList = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList';
static final String getOnlineAncillaryOrderProcList = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList';
static final String generateAncillaryOrderInvoice = 'Services/Doctors.svc/REST/AutoGenerateAncillaryOrderInvoice';
static final String autoGenerateAncillaryOrdersInvoice = 'Services/Doctors.svc/REST/AutoGenerateAncillaryOrderInvoice';
static final String getRequestStatusByRequestID = 'Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID';
//Payment APIs
static final String applePayInsertRequest = "Services/PayFort_Serv.svc/REST/PayFort_ApplePayRequestData_Insert";
static final String createAdvancePayments = 'Services/Patients.svc/REST/HIS_CreateAdvancePayment';
static final String addAdvanceNumberRequest = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest';
// RC COMPREHENSIVE MEDICAL CHECKUP ServIces
static final String allCMCOrdersRc = 'api/cmc/list';
static final String allCMCServicesRc = 'api/cmc/getallcmc';
static final String updateCMCOrder = 'api/cmc/update';
static final String addCMCOrder = 'api/cmc/add';
static final String getHospitalsList = 'Services/Lists.svc/REST/GetProject';
// RC HOME HEALTHCARE ServIces
static final String allHHCOrdersRc = 'api/hhc/list';
static final String allHHCServicesRc = 'api/HHC/getallhhc';
static final String updateHHCOrder = 'api/hhc/update';
static final String addHHCOrder = 'api/HHC/add';
// SYMPTOMS CHECKER API
static final String symptomsUserLogin = '$symptomsCheckerApi/user_login';
static final String getBodySymptomsByName = '$symptomsCheckerApi/GetBodySymptomsByName';
static final String getRiskFactors = '$symptomsCheckerApi/GetRiskFactors';
static final String getSuggestions = '$symptomsCheckerApi/GetSuggestion';
static final String diagnosis = '$symptomsCheckerApi/GetDiagnosis';
static final String explain = '$symptomsCheckerApi/ExplainDiagnosisResult';
static final String getClinicFromCondition = '$symptomsCheckerApi/GetClinicsByCondition?condition=';
//E-REFERRAL SERVICES
static final getAllRelationshipTypes = "Services/Patients.svc/REST/GetAllRelationshipTypes";
static final sendActivationCodeForEReferral = 'Services/Authentication.svc/REST/SendActivationCodeForEReferral';
static final checkActivationCodeForEReferral = 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral';
static final getAllCities = 'services/Lists.svc/rest/GetAllCities';
static final createEReferral = "Services/Patients.svc/REST/CreateEReferral";
static final getEReferrals = "Services/Patients.svc/REST/GetEReferrals";
//WATER CONSUMPTION
static String h2oGetUserProgress = "Services/H2ORemainder.svc/REST/H2O_GetUserProgress";
static String h2oInsertUserActivity = "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity";
static String h2oInsertUserDetailsNew = "Services/H2ORemainder.svc/REST/H2O_InsertUserDetails_New";
static String h2oGetUserDetail = "Services/H2ORemainder.svc/REST/H2O_GetUserDetails_New";
static String h2oUpdateUserDetail = "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New";
static String h2oUndoUserActivity = "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity";
// HEALTH TRACKERS
// Blood Sugar (Diabetic)
static String getDiabeticResultAverage = 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage';
static String getDiabeticResult = 'Services/Patients.svc/REST/Patient_GetDiabtecResults';
static String addDiabeticResult = 'Services/Patients.svc/REST/Patient_AddDiabtecResult';
static String updateDiabeticResult = 'Services/Patients.svc/REST/Patient_UpdateDiabtecResult';
static String deactivateDiabeticStatus = 'Services/Patients.svc/REST/Patient_DeactivateDiabeticStatus';
static String sendAverageBloodSugarReport = 'Services/Notifications.svc/REST/SendAverageBloodSugarReport';
// Blood Pressure
static String getBloodPressureResultAverage = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage';
static String getBloodPressureResult = 'Services/Patients.svc/REST/Patient_GetBloodPressureResult';
static String addBloodPressureResult = 'Services/Patients.svc/REST/Patient_AddBloodPressureResult';
static String updateBloodPressureResult = 'Services/Patients.svc/REST/Patient_UpdateBloodPressureResult';
static String deactivateBloodPressureStatus = 'Services/Patients.svc/REST/Patient_DeactivateBloodPressureStatus';
static String sendAverageBloodPressureReport = 'Services/Notifications.svc/REST/SendAverageBloodPressureReport';
// Weight Measurement
static String getWeightMeasurementResultAverage = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage';
static String getWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult';
static String addWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult';
static String updateWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_UpdateWeightMeasurementResult';
static String deactivateWeightMeasurementStatus = 'Services/Patients.svc/REST/Patient_DeactivateWeightMeasurementStatus';
static String sendAverageBodyWeightReport = 'Services/Notifications.svc/REST/SendAverageBodyWeightReport';
//Blood Donation
static String bloodGroupUpdate = "Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType";
static String userAgreementForBloodGroupUpdate = "Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation";
static String getProjectsHaveBDClinics = "Services/OUTPs.svc/REST/BD_getProjectsHaveBDClinics";
static String getClinicsBDFreeSlots = "Services/OUTPs.svc/REST/BD_GetFreeSlots";
static String getPatientBloodGroup = "services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails";
static String getPatientBloodAgreement = "Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation";
static String getAiOverViewLabOrders = "Services/Patients.svc/REST/HMGAI_Lab_Analyze_Orders_API";
static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API";
// ************ static values for Api ****************
static final double appVersionID = 19.7;
// static final double appVersionID = 50.7;
static final int appChannelId = 3;
static final String appIpAddress = "10.20.10.20";
static final String appGeneralId = "Cs2020@2016\$2958";
static final String sessionID = 'TMRhVmkGhOsvamErw';
}
// PACKAGES and OFFERS
var EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/offersdiscounts';
// var EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000';
@ -680,242 +916,6 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb
const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
static String baseUrl = 'https://hmgwebservices.com/'; // HIS API URL PROD
static String rcBaseUrl = 'https://rc.hmg.com/'; // dRC API URL PROD
static String hmgPharmacyApiBaseUrl = 'https://hmgpharmacyapi.hmg.com/'; // dRC API URL PROD
static String symptomsCheckerApi = '${hmgPharmacyApiBaseUrl}symptomsapi/api/SymptomChecker'; // dRC API URL PROD
static var payFortEnvironment = FortEnvironment.production;
static var applePayMerchantId = "merchant.com.hmgwebservices";
static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE
// static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT
static String TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
static String GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
static String GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
static String QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
static String CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId=";
// static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
// var payFortEnvironment = FortEnvironment.test;
// var applePayMerchantId = "merchant.com.hmgwebservices.uat";
static setBackendURLs() {
switch (appEnvironmentType) {
case AppEnvironmentTypeEnum.prod:
baseUrl = "https://hmgwebservices.com/";
payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices";
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId=";
break;
case AppEnvironmentTypeEnum.dev:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/";
payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices";
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.qa:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/";
payFortEnvironment = FortEnvironment.test;
applePayMerchantId = "merchant.com.hmgwebservices.uat";
SERVICE_URL = 'https://uat.hmgwebservices.com/HMGPayment/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
rcBaseUrl = 'https://rc.hmg.com/uat/';
QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail";
CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId";
break;
}
}
static final String selectDeviceImei = 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI';
static final String checkPatientAuth = 'Services/Authentication.svc/REST/CheckPatientAuthentication';
static final String sendActivationCode = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType';
static final String sendActivationCodeRegister = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration';
static final String checkActivationCode = 'Services/Authentication.svc/REST/CheckActivationCode';
static final String checkActivationCodeRegister = 'Services/Authentication.svc/REST/CheckActivationCodeForRegistration';
static final String checkUsageAgreement = 'Services/Patients.svc/REST/CheckForUsageAgreement';
static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText';
static final String checkPatientForRegistration = 'Services/Authentication.svc/REST/CheckPatientForRegisteration';
static final String checkUserStatus = 'Services/NHIC.svc/REST/GetPatientInfo';
static final String insertPatientDeviceIMEIData = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI';
static final String insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo';
static final String getPatientMobileData = '/Services/Authentication.svc/REST/GetMobileLoginInfo';
static final String getPrivileges = 'Services/Patients.svc/REST/Service_Privilege';
static final String registerUser = 'Services/Authentication.svc/REST/PatientRegistration';
static final String addFamilyFile = 'Services/Patients.svc/REST/ShareFamilyFileService';
static final String sendFamilyFileActivation = 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile';
static final String checkActivationCodeForFamily = 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile';
static final String getAllPendingRecordsByResponseId = 'Services/Authentication.svc/REST/GetAllPendingRecordsByResponseId';
static final String getAllSharedRecordsByStatus = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus';
static final String removeFileFromFamilyMembers = 'Services/Authentication.svc/REST/ActiveDeactive_PatientFile';
static final String acceptAndRejectFamilyFile = 'Services/Authentication.svc/REST/Update_FileStatus';
static final String getActivePrescriptionsDetails = 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID';
static final String getTermsConditions = 'Services/Patients.svc/Rest/GetUserTermsAndConditions';
static final String getMonthlyReports = 'Services/Patients.svc/Rest/UpdatePateintHealthSummaryReport';
static final String updatePatientEmail = 'Services/Patients.svc/Rest/UpdatePateintEmail';
static final String getQrParkingDetails = 'Services/SWP.svc/REST/GetQRParkingByID';
// Ancillary Order Apis
static final String getOnlineAncillaryOrderList = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList';
static final String getOnlineAncillaryOrderProcList = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList';
static final String generateAncillaryOrderInvoice = 'Services/Doctors.svc/REST/AutoGenerateAncillaryOrderInvoice';
static final String autoGenerateAncillaryOrdersInvoice = 'Services/Doctors.svc/REST/AutoGenerateAncillaryOrderInvoice';
static final String getRequestStatusByRequestID = 'Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID';
//Payment APIs
static final String applePayInsertRequest = "Services/PayFort_Serv.svc/REST/PayFort_ApplePayRequestData_Insert";
static final String createAdvancePayments = 'Services/Patients.svc/REST/HIS_CreateAdvancePayment';
static final String addAdvanceNumberRequest = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest';
// RC COMPREHENSIVE MEDICAL CHECKUP ServIces
static final String allCMCOrdersRc = 'api/cmc/list';
static final String allCMCServicesRc = 'api/cmc/getallcmc';
static final String updateCMCOrder = 'api/cmc/update';
static final String addCMCOrder = 'api/cmc/add';
static final String getHospitalsList = 'Services/Lists.svc/REST/GetProject';
// RC HOME HEALTHCARE ServIces
static final String allHHCOrdersRc = 'api/hhc/list';
static final String allHHCServicesRc = 'api/HHC/getallhhc';
static final String updateHHCOrder = 'api/hhc/update';
static final String addHHCOrder = 'api/HHC/add';
// SYMPTOMS CHECKER API
static final String symptomsUserLogin = '$symptomsCheckerApi/user_login';
static final String getBodySymptomsByName = '$symptomsCheckerApi/GetBodySymptomsByName';
static final String getRiskFactors = '$symptomsCheckerApi/GetRiskFactors';
static final String getSuggestions = '$symptomsCheckerApi/GetSuggestion';
static final String diagnosis = '$symptomsCheckerApi/GetDiagnosis';
static final String explain = '$symptomsCheckerApi/ExplainDiagnosisResult';
//E-REFERRAL SERVICES
static final getAllRelationshipTypes = "Services/Patients.svc/REST/GetAllRelationshipTypes";
static final sendActivationCodeForEReferral = 'Services/Authentication.svc/REST/SendActivationCodeForEReferral';
static final checkActivationCodeForEReferral = 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral';
static final getAllCities = 'services/Lists.svc/rest/GetAllCities';
static final createEReferral = "Services/Patients.svc/REST/CreateEReferral";
static final getEReferrals = "Services/Patients.svc/REST/GetEReferrals";
//WATER CONSUMPTION
static String h2oGetUserProgress = "Services/H2ORemainder.svc/REST/H2O_GetUserProgress";
static String h2oInsertUserActivity = "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity";
static String h2oInsertUserDetailsNew = "Services/H2ORemainder.svc/REST/H2O_InsertUserDetails_New";
static String h2oGetUserDetail = "Services/H2ORemainder.svc/REST/H2O_GetUserDetails_New";
static String h2oUpdateUserDetail = "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New";
static String h2oUndoUserActivity = "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity";
// HEALTH TRACKERS
// Blood Sugar (Diabetic)
static String getDiabeticResultAverage = 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage';
static String getDiabeticResult = 'Services/Patients.svc/REST/Patient_GetDiabtecResults';
static String addDiabeticResult = 'Services/Patients.svc/REST/Patient_AddDiabtecResult';
static String updateDiabeticResult = 'Services/Patients.svc/REST/Patient_UpdateDiabtecResult';
static String deactivateDiabeticStatus = 'Services/Patients.svc/REST/Patient_DeactivateDiabeticStatus';
static String sendAverageBloodSugarReport = 'Services/Notifications.svc/REST/SendAverageBloodSugarReport';
// Blood Pressure
static String getBloodPressureResultAverage = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage';
static String getBloodPressureResult = 'Services/Patients.svc/REST/Patient_GetBloodPressureResult';
static String addBloodPressureResult = 'Services/Patients.svc/REST/Patient_AddBloodPressureResult';
static String updateBloodPressureResult = 'Services/Patients.svc/REST/Patient_UpdateBloodPressureResult';
static String deactivateBloodPressureStatus = 'Services/Patients.svc/REST/Patient_DeactivateBloodPressureStatus';
static String sendAverageBloodPressureReport = 'Services/Notifications.svc/REST/SendAverageBloodPressureReport';
// Weight Measurement
static String getWeightMeasurementResultAverage = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage';
static String getWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult';
static String addWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult';
static String updateWeightMeasurementResult = 'Services/Patients.svc/REST/Patient_UpdateWeightMeasurementResult';
static String deactivateWeightMeasurementStatus = 'Services/Patients.svc/REST/Patient_DeactivateWeightMeasurementStatus';
static String sendAverageBodyWeightReport = 'Services/Notifications.svc/REST/SendAverageBodyWeightReport';
//Blood Donation
static String bloodGroupUpdate = "Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType";
static String userAgreementForBloodGroupUpdate = "Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation";
static String getProjectsHaveBDClinics = "Services/OUTPs.svc/REST/BD_getProjectsHaveBDClinics";
static String getClinicsBDFreeSlots = "Services/OUTPs.svc/REST/BD_GetFreeSlots";
static String getPatientBloodGroup = "services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails";
static String getPatientBloodAgreement = "Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation";
static String getAiOverViewLabOrders = "Services/Patients.svc/REST/HMGAI_Lab_Analyze_Orders_API";
static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API";
// ************ static values for Api ****************
// static final double appVersionID = 19.7;
static final double appVersionID = 50.7;
static final int appChannelId = 3;
static final String appIpAddress = "10.20.10.20";
static final String appGeneralId = "Cs2020@2016\$2958";
static final String sessionID = 'TMRhVmkGhOsvamErw';
}
class ApiKeyConstants {
static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng';
}

@ -295,6 +295,10 @@ class AppAssets {
static const String bulb = '$svgBasePath/bulb.svg';
static const String switchBtn = '$svgBasePath/switch.svg';
static const String livecare_video = '$svgBasePath/livecare_video.svg';
static const String livecare_audio = '$svgBasePath/livecare_audio.svg';
static const String livecare_phone = '$svgBasePath/livecare_phone.svg';
//Health Trackers
static const String bloodPressureIcon = '$svgBasePath/blood_pressure_icon.svg';
static const String bloodSugarOnlyIcon = '$svgBasePath/blood_sugar_only_icon.svg';

@ -12,13 +12,17 @@ class PenguinMethodChannel {
try {
await _channel.invokeMethod('launchPenguin', {
"storyboardName": storyboardName,
"baseURL": "https://penguinuat.hmg.com",
// "dataURL": "https://hmg.nav.penguinin.com",
// "positionURL": "https://hmg.nav.penguinin.com",
// "dataURL": "https://hmg-v33.local.penguinin.com",
// "positionURL": "https://hmg-v33.local.penguinin.com",
"dataURL": "https://penguinuat.hmg.com",
"positionURL": "https://penguinuat.hmg.com",
// UAT URLs
// "baseURL": "https://penguinuat.hmg.com",
// "dataURL": "https://penguinuat.hmg.com",
// "positionURL": "https://penguinuat.hmg.com",
// Prod URLs
"baseURL": "https://eagleiq.hmg.com",
"dataURL": "https://eagleiq.hmg.com",
"positionURL": "https://eagleiq.hmg.com",
"dataServiceName": "api",
"positionServiceName": "pe",
"clientID": "HMG",

@ -95,7 +95,7 @@ _incomingCall(Map<String, dynamic> data) async {
missedCallNotificationChannelName: "Missed Call",
isShowCallID: false),
ios: IOSParams(
iconName: 'Meena Health',
iconName: 'CallKitLogo',
handleType: 'generic',
supportsVideo: true,
maximumCallGroups: 2,

@ -408,6 +408,8 @@ class Utils {
Widget? bodyWidget,
Function? onConfirmTap,
Function? onCancelTap,
String? cancelText,
String? confirmText,
}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
@ -425,7 +427,7 @@ class Utils {
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
text: cancelText ?? LocaleKeys.cancel.tr(),
onPressed: () {
if (onCancelTap != null) {
onCancelTap();
@ -434,14 +436,14 @@ class Utils {
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
// icon: AppAssets.cancel,
// iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
text: confirmText ?? LocaleKeys.confirm.tr(),
onPressed: () async {
if (onConfirmTap != null) {
onConfirmTap();
@ -450,7 +452,7 @@ class Utils {
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
// icon: AppAssets.confirm,
),
),
],
@ -988,6 +990,12 @@ class Utils {
return isAllowed;
}
static bool containsArabic(String text) {
// Using Unicode range for Arabic characters
final RegExp arabicRegex = RegExp(r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]');
return arabicRegex.hasMatch(text);
}
static String toEnglishNumbers(String input) {
const english = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const arabic = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];

@ -192,6 +192,7 @@ extension EmailValidator on String {
int? maxlines,
double? letterSpacing = 0,
double? height,
String? fontFamily,
TextOverflow? textOverflow,
}) =>
Text(
@ -206,7 +207,7 @@ extension EmailValidator on String {
height: height,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
decoration: isUnderLine ? TextDecoration.underline : null,
fontFamily: isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins',
fontFamily: fontFamily ?? (isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),
decorationColor: color ?? AppColors.blackColor),
);
@ -231,12 +232,13 @@ extension EmailValidator on String {
TextAlign? textAlign,
FontWeight? weight,
TextOverflow? textOverflow,
String? fontFamily,
double? letterSpacing = -0.4,
Color decorationColor = AppColors.errorColor}) =>
Text(
this,
maxLines: maxlines,
textAlign: isCenter ? TextAlign.center : null,
textAlign: isCenter ? textAlign ?? TextAlign.center : null,
// locale: Locale('en', 'US'),
style: TextStyle(
color: color ?? AppColors.blackColor,
@ -246,7 +248,7 @@ extension EmailValidator on String {
overflow: textOverflow,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
decoration: isUnderLine ? TextDecoration.underline : null,
fontFamily: isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins',
fontFamily: fontFamily ?? (isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),
decorationColor: decorationColor),
);

@ -847,7 +847,7 @@ class AuthenticationViewModel extends ChangeNotifier {
} else {
LoadingUtils.hideFullScreenLoader();
if (apiResponse.data["MessageStatus"] == 1) {
LoadingUtils.showFullScreenLoader(isSuccessDialog: true);
LoadingUtils.showFullScreenLoader(isSuccessDialog: true, loadingText: "Your medical file has been created successfully. \nPlease proceed to login.");
//TODO: Here We Need to Show a Dialog Of Something in the case of Success.
await clearDefaultInputValues(); // This will Clear All Default Values Of User.
Future.delayed(Duration(seconds: 1), () {
@ -1064,7 +1064,10 @@ class AuthenticationViewModel extends ChangeNotifier {
List<ProjectDetailListModel> projectDetailListModel = [];
resultEither.fold(
(failure) async => await _errorHandlerService.handleError(failure: failure),
// (failure) async => await _errorHandlerService.handleError(failure: failure),
(failure) async {
print(failure.message);
},
(apiResponse) async {
if (apiResponse.messageStatus == 2) {
await _dialogService.showErrorBottomSheet(message: apiResponse.errorMessage ?? "ErrorEmpty");

@ -34,6 +34,7 @@ import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'models/resp_models/get_livecare_clinics_response_model.dart';
@ -838,16 +839,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
appointmentDate: apiResponse.data["SameClinicApptList"][0]['AppointmentDate'],
);
showCommonBottomSheet(navigationService.navigatorKey.currentContext!,
child: Utils.getLoadingWidget(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr()),
callBackFunc: (str) {},
title: "",
height: ResponsiveExtension.screenHeight * 0.3,
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false);
LoaderBottomSheet.showLoader(
loadingText: LocaleKeys.reschedulingAppo.tr(context: navigationService.navigatorKey.currentContext!),
);
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
navigationService.pop();
LoaderBottomSheet.hideLoader();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: LocaleKeys.bookingYourAppointment.tr());
await insertSpecificAppointment(

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/req_models/request_insert_coc_item.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_patient_ic_projects.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_status_coc_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
@ -17,6 +18,8 @@ abstract class ContactUsRepo {
Future<Either<Failure, GenericApiModel<String>>> getChatRequestID({required String name, required String mobileNo, required String workGroup});
Future<Either<Failure, GenericApiModel<dynamic>>> insertCOCItem({required RequestInsertCOCItem requestInsertCOCItem, PatientAppointmentHistoryResponseModel? patientSelectedAppointment});
Future<Either<Failure, GenericApiModel<List<COCItem>>>> getStatusForCOC(String identificationNo, String mobileNo, {Function(dynamic)? onSuccess, Function(String)? onError});
}
class ContactUsRepoImp implements ContactUsRepo {
@ -181,4 +184,44 @@ class ContactUsRepoImp implements ContactUsRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<COCItem>>>> getStatusForCOC(String identificationNo, String mobileNo, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> body = {};
body['IdentificationNo'] = identificationNo;
body['MobileNo'] = mobileNo;
body['Searching_type'] = 1;
try {
GenericApiModel<List<COCItem>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_STATUS_FOR_COCO,
body: body,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['ListCOCItems'];
final cocItemsList = list.map((item) => COCItem.fromJson(item as Map<String, dynamic>)).toList().cast<COCItem>();
apiResponse = GenericApiModel<List<COCItem>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: cocItemsList,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
}

@ -9,6 +9,7 @@ import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dar
import 'package:hmg_patient_app_new/features/contact_us/models/req_models/request_insert_coc_item.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_patient_ic_projects.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_status_coc_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
@ -33,6 +34,9 @@ class ContactUsViewModel extends ChangeNotifier {
List<String> feedbackAttachmentList = [];
List<COCItem> cocItemsList = [];
bool isCOCItemsListLoading = false;
PatientAppointmentHistoryResponseModel? patientFeedbackSelectedAppointment;
List<FeedbackType> feedbackTypeList = [
@ -52,10 +56,12 @@ class ContactUsViewModel extends ChangeNotifier {
isHMGLocationsListLoading = true;
isHMGHospitalsListSelected = true;
isLiveChatProjectsListLoading = true;
isCOCItemsListLoading = true;
hmgHospitalsLocationsList.clear();
hmgPharmacyLocationsList.clear();
liveChatProjectsList.clear();
feedbackAttachmentList.clear();
cocItemsList.clear();
selectedFeedbackType = FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد');
setPatientFeedbackSelectedAppointment(null);
getHMGLocations();
@ -74,6 +80,9 @@ class ContactUsViewModel extends ChangeNotifier {
setIsSendFeedbackTabSelected(bool isSelected) {
isSendFeedbackTabSelected = isSelected;
if (!isSelected) {
getStatusForCOC(identificationNo: appState.getAuthenticatedUser()!.patientIdentificationNo!, mobileNo: "966${Utils.getPhoneNumberWithoutZero(appState.getAuthenticatedUser()!.mobileNumber!)}");
}
notifyListeners();
}
@ -223,4 +232,38 @@ class ContactUsViewModel extends ChangeNotifier {
},
);
}
Future<void> getStatusForCOC({required String identificationNo, required String mobileNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
isCOCItemsListLoading = true;
cocItemsList.clear();
notifyListeners();
final result = await contactUsRepo.getStatusForCOC(identificationNo, mobileNo);
result.fold(
(failure) async {
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
isCOCItemsListLoading = false;
onError(failure.toString());
}
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
if (onError != null) {
isCOCItemsListLoading = false;
onError(apiResponse.errorMessage ?? 'Unknown error');
}
} else if (apiResponse.messageStatus == 1) {
cocItemsList = apiResponse.data!;
cocItemsList.sort((a, b) => a.date!.compareTo(b.date!));
isCOCItemsListLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
}

@ -0,0 +1,124 @@
class COCItem {
dynamic appointment;
String? appointmentClinicName;
String? appointmentDate;
String? appointmentProjectName;
String? cOCID;
String? cOCTitle;
String? channel;
dynamic clinic;
String? clinicID;
String? date;
dynamic detail;
dynamic doctor;
String? doctorID;
String? formType;
int? formTypeID;
dynamic identificationNo;
int? itemID;
dynamic mobileNo;
dynamic naturename;
dynamic patientID;
dynamic patientName;
dynamic project;
dynamic projectID;
String? solution;
String? status;
String? statusAr;
dynamic statusEn;
int? statusId;
COCItem({
this.appointment,
this.appointmentClinicName,
this.appointmentDate,
this.appointmentProjectName,
this.cOCID,
this.cOCTitle,
this.channel,
this.clinic,
this.clinicID,
this.date,
this.detail,
this.doctor,
this.doctorID,
this.formType,
this.formTypeID,
this.identificationNo,
this.itemID,
this.mobileNo,
this.naturename,
this.patientID,
this.patientName,
this.project,
this.projectID,
this.solution,
this.status,
this.statusAr,
this.statusEn,
this.statusId,
});
COCItem.fromJson(Map<String, dynamic> json) {
appointment = json['Appointment'];
appointmentClinicName = json['AppointmentClinicName'];
appointmentDate = json['AppointmentDate'];
appointmentProjectName = json['AppointmentProjectName'];
cOCID = json['COCID'];
cOCTitle = json['COCTitle'];
channel = json['Channel'];
clinic = json['Clinic'];
clinicID = json['ClinicID'];
date = json['Date'];
detail = json['Detail'];
doctor = json['Doctor'];
doctorID = json['DoctorID'];
formType = json['FormType'];
formTypeID = json['FormTypeID'];
identificationNo = json['IdentificationNo'];
itemID = json['ItemID'];
mobileNo = json['MobileNo'];
naturename = json['Naturename'];
patientID = json['PatientID'];
patientName = json['PatientName'];
project = json['Project'];
projectID = json['ProjectID'];
solution = json['Solution'];
status = json['Status'];
statusAr = json['StatusAr'];
statusEn = json['StatusEn'];
statusId = json['StatusId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Appointment'] = this.appointment;
data['AppointmentClinicName'] = this.appointmentClinicName;
data['AppointmentDate'] = this.appointmentDate;
data['AppointmentProjectName'] = this.appointmentProjectName;
data['COCID'] = this.cOCID;
data['COCTitle'] = this.cOCTitle;
data['Channel'] = this.channel;
data['Clinic'] = this.clinic;
data['ClinicID'] = this.clinicID;
data['Date'] = this.date;
data['Detail'] = this.detail;
data['Doctor'] = this.doctor;
data['DoctorID'] = this.doctorID;
data['FormType'] = this.formType;
data['FormTypeID'] = this.formTypeID;
data['IdentificationNo'] = this.identificationNo;
data['ItemID'] = this.itemID;
data['MobileNo'] = this.mobileNo;
data['Naturename'] = this.naturename;
data['PatientID'] = this.patientID;
data['PatientName'] = this.patientName;
data['Project'] = this.project;
data['ProjectID'] = this.projectID;
data['Solution'] = this.solution;
data['Status'] = this.status;
data['StatusAr'] = this.statusAr;
data['StatusEn'] = this.statusEn;
return data;
}
}

@ -1,16 +1,26 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_repo.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/models/resp_models/get_livecare_immediate_clinics_response_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/models/resp_models/get_livecare_immediate_fees_response_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/models/resp_models/get_patient_livecare_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import '../../services/navigation_service.dart';
@ -42,6 +52,9 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
late ValueNotifier<Duration> durationNotifier;
late Timer timer;
bool isShowNotEligibleDialog = false;
String notEligibleErrorMsg = "";
initImmediateLiveCare() {
_appState = getIt<AppState>();
immediateLiveCareClinicsList = [];
@ -102,8 +115,80 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
liveCareImmediateAppointmentFeesList = apiResponse.data!;
if ((liveCareImmediateAppointmentFeesList.isCash!)) {
isShowNotEligibleDialog = false;
} else {
if (liveCareImmediateAppointmentFeesList.isInsured! && liveCareImmediateAppointmentFeesList.isEligible!) {
isShowNotEligibleDialog = false;
} else {
if (liveCareImmediateAppointmentFeesList.isInsured! && liveCareImmediateAppointmentFeesList.isEligible!) {
isShowNotEligibleDialog = true;
notEligibleErrorMsg = LocaleKeys.invalidEligibility.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!);
} else {
isShowNotEligibleDialog = true;
notEligibleErrorMsg = LocaleKeys.invalidInsurance.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!);
}
}
}
if (isShowNotEligibleDialog) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: Padding(
padding: EdgeInsets.only(
left: 24.w,
top: 24.h,
right: 24.w,
bottom: 12.h,
),
child: Utils.getWarningWidget(
loadingText: notEligibleErrorMsg,
confirmText: LocaleKeys.updateInsuranceInfo.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
cancelText: LocaleKeys.continueCash.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
LoaderBottomSheet.showLoader();
myAppointmentsViewModel.convertPatientToCash(
projectID: ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat ? 15 : 12,
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingFeesPleaseWait.tr());
getLiveCareImmediateAppointmentFees();
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: Utils.getErrorWidget(loadingText: err.toString()),
callBackFunc: () {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
},
onConfirmTap: () async {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.push(
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
CustomPageRoute(
page: InsuranceHomePage(),
),
);
}),
), callBackFunc: () {
// Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
}, isFullScreen: false, isCloseButtonVisible: false, isDismissible: false);
}
notifyListeners();
if (onSuccess != null) {
if (onSuccess != null && !isShowNotEligibleDialog) {
onSuccess(apiResponse);
}
}

@ -18,6 +18,7 @@ class InsuranceViewModel extends ChangeNotifier {
bool isInsuranceApprovalsLoading = false;
bool isInsuranceExpired = false;
bool isInsuranceActive = false;
InsuranceRepo insuranceRepo;
ErrorHandlerService errorHandlerService;
@ -79,6 +80,8 @@ class InsuranceViewModel extends ChangeNotifier {
(failure) async {
isInsuranceLoading = false;
isInsuranceDataToBeLoaded = false;
isInsuranceExpired = false;
isInsuranceActive = false;
notifyListeners();
},
(apiResponse) {
@ -94,6 +97,9 @@ class InsuranceViewModel extends ChangeNotifier {
DateUtil.convertStringToDate(patientInsuranceList.first.cardValidTo),
);
isInsuranceActive = patientInsuranceList.first.isActive ?? false;
// isInsuranceActive = true;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);

@ -17,7 +17,7 @@ import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_
import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_results/lab_result_details.dart';
import 'package:hmg_patient_app_new/presentation/labAiAnalysis/lab_ai_analysis_detailed_page.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/lab_ai_analysis_detailed_page.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';

@ -73,6 +73,8 @@ abstract class MyAppointmentsRepo {
Future<Either<Failure, GenericApiModel<void>>> sendDoctorRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName);
Future<Either<Failure, GenericApiModel<List<PatientQueueDetails>>>> getPatientAppointmentQueueDetails({required int appointmentNo, required int patientID});
Future<Either<Failure, GenericApiModel<dynamic>>> convertPatientToCash({required int projectID});
}
class MyAppointmentsRepoImp implements MyAppointmentsRepo {
@ -957,4 +959,36 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
}
}
@override
Future<Either<Failure, GenericApiModel>> convertPatientToCash({required int projectID}) async {
Map<String, dynamic> request;
request = {"ProjectID": projectID};
try {
GenericApiModel<bool>? apiResponse;
Failure? failure;
await apiClient.post(CONVERT_PATIENT_TO_CASH, onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
}, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = (response['MessageStatus'] == 1);
apiResponse = GenericApiModel<bool>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: list,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
}, body: request);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
}

@ -1,6 +1,9 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart';
@ -10,7 +13,13 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_queue_details_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
class MyAppointmentsViewModel extends ChangeNotifier {
int selectedTabIndex = 0;
@ -73,6 +82,9 @@ class MyAppointmentsViewModel extends ChangeNotifier {
GetTamaraInstallmentsDetailsResponseModel? getTamaraInstallmentsDetailsResponseModel;
bool isTamaraDetailsLoading = false;
bool isShowNotEligibleDialog = false;
String notEligibleErrorMsg = "";
MyAppointmentsViewModel({required this.myAppointmentsRepo, required this.errorHandlerService, required this.appState});
void onTabChange(int index) {
@ -141,6 +153,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
isTamaraDetailsLoading = true;
isAppointmentPatientShareLoading = true;
isEyeMeasurementsAppointmentsLoading = true;
isShowNotEligibleDialog = false;
notifyListeners();
}
@ -349,7 +362,99 @@ class MyAppointmentsViewModel extends ChangeNotifier {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
patientAppointmentShareResponseModel = apiResponse.data!;
if ((patientAppointmentShareResponseModel!.isCash!)) {
isShowNotEligibleDialog = false;
} else {
if (patientAppointmentShareResponseModel!.isInsured! && patientAppointmentShareResponseModel!.isEligible!) {
isShowNotEligibleDialog = false;
} else {
if (patientAppointmentShareResponseModel!.isInsured! && patientAppointmentShareResponseModel!.isEligible!) {
isShowNotEligibleDialog = true;
notEligibleErrorMsg = LocaleKeys.invalidEligibility.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!);
} else {
isShowNotEligibleDialog = true;
notEligibleErrorMsg = LocaleKeys.invalidInsurance.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!);
}
}
}
isAppointmentPatientShareLoading = false;
if (isShowNotEligibleDialog) {
showCommonBottomSheetWithoutHeight(GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: Padding(
padding: EdgeInsets.only(
left: 24.w,
top: 24.h,
right: 24.w,
bottom: 12.h,
),
child: Utils.getWarningWidget(
loadingText: notEligibleErrorMsg,
confirmText: LocaleKeys.updateInsuranceInfo.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
cancelText: LocaleKeys.continueCash.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
LoaderBottomSheet.showLoader();
convertPatientToCash(
projectID: projectID,
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
setIsPatientAppointmentShareLoading(true);
getPatientShareAppointment(projectID, clinicID, appointmentNo, isLiveCareAppointment);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: Utils.getErrorWidget(loadingText: err.toString()),
callBackFunc: () {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
},
onConfirmTap: () async {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
Navigator.push(
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
CustomPageRoute(
page: InsuranceHomePage(),
),
);
}),
), callBackFunc: () {
// Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
}, isFullScreen: false, isCloseButtonVisible: false, isDismissible: false);
}
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> convertPatientToCash({required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.convertPatientToCash(projectID: projectID);
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async {
onError!(failure.message);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
@ -413,7 +518,12 @@ class MyAppointmentsViewModel extends ChangeNotifier {
final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
// (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async {
if(onError != null) {
onError(failure.message);
}
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);

@ -188,7 +188,7 @@ class PrescriptionsRepoImp implements PrescriptionsRepo {
Map<String, dynamic> mapDevice = {
"AppointmentNo": prescriptionsResponseModel.appointmentNo,
"SetupID": prescriptionsResponseModel.setupID,
"EpisodeID": prescriptionsResponseModel.episodeID,
"EpisodeNo": prescriptionsResponseModel.episodeID,
"ClinicID": prescriptionsResponseModel.clinicID,
"ProjectID": prescriptionsResponseModel.projectID,
"DischargeNo": prescriptionsResponseModel.dischargeNo,

@ -153,7 +153,10 @@ class PrescriptionsViewModel extends ChangeNotifier {
final result = await prescriptionsRepo.getPatientPrescriptionDetails(prescriptionsResponseModel: prescriptionsResponseModel);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
// (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async {
onError!(failure.message);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});

@ -121,7 +121,7 @@ class RadiologyRepoImp implements RadiologyRepo {
Map<String, dynamic> mapDevice = {
"InvoiceNo": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? 0 : patientRadiologyResponseModel.invoiceNo,
"InvoiceNo_VP": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? patientRadiologyResponseModel.invoiceNo : 0,
"LineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
// "LineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
"InvoiceLineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
"ProjectID": patientRadiologyResponseModel.projectID!,
"InvoiceType": patientRadiologyResponseModel.invoiceType!,

@ -0,0 +1,25 @@
class GetClinicDetailsResponseModel {
String? category;
int? clinicID;
bool? isActive;
String? categoryAR;
GetClinicDetailsResponseModel(
{this.category, this.clinicID, this.isActive, this.categoryAR});
GetClinicDetailsResponseModel.fromJson(Map<String, dynamic> json) {
category = json['Category'];
clinicID = json['ClinicID'];
isActive = json['IsActive'];
categoryAR = json['CategoryAR'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Category'] = this.category;
data['ClinicID'] = this.clinicID;
data['IsActive'] = this.isActive;
data['CategoryAR'] = this.categoryAR;
return data;
}
}

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/body_symptom_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/get_clinic_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/symptoms_user_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
@ -50,6 +51,11 @@ abstract class SymptomsCheckerRepo {
required String userSessionToken,
required String sessionId,
});
Future<Either<Failure, GenericApiModel<List<GetClinicDetailsResponseModel>>>> getClinicDetails({
required String categoryName,
required String userSessionToken,
});
}
class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
@ -390,4 +396,57 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<GetClinicDetailsResponseModel>>>> getClinicDetails({
required String categoryName,
required String userSessionToken,
}) async {
Map<String, String> headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $userSessionToken',
};
Map<String, dynamic> body = {};
try {
GenericApiModel<List<GetClinicDetailsResponseModel>>? apiResponse;
Failure? failure;
await apiClient.get(
"${ApiConsts.getClinicFromCondition}$categoryName",
apiHeaders: headers,
isExternal: true,
isAllowAny: true,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType ?? ServerFailure(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
final clinicDetails;
try {
final list = response['dataDetails'];
clinicDetails = list.map((item) => GetClinicDetailsResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<GetClinicDetailsResponseModel>();
apiResponse = GenericApiModel<List<GetClinicDetailsResponseModel>>(
messageStatus: messageStatus ?? 1,
statusCode: statusCode,
errorMessage: errorMessage,
data: clinicDetails,
);
} catch (e, stackTrace) {
loggerService.logError("Error parsing GetClinicsByCondition response: $e");
loggerService.logError("StackTrace: $stackTrace");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e, stackTrace) {
loggerService.logError("Exception in GetClinicsByCondition: $e");
loggerService.logError("StackTrace: $stackTrace");
return Left(UnknownFailure(e.toString()));
}
}
}

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/data/organ_mapping_data.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/organ_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/body_symptom_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/get_clinic_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/symptoms_user_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
@ -154,6 +155,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
/// Get the number of triage questions answered
int get triageQuestionCount => _triageQuestionCount;
List<GetClinicDetailsResponseModel> clinicDetailsList = [];
/// Get choice index for a specific item
int? getTriageChoiceForItem(String itemId) {
return _selectedTriageChoicesByItemId[itemId];
@ -1066,6 +1069,43 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
);
}
Future<void> getClinicConditionsFromCategory({
required String categoryName,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
clinicDetailsList.clear();
notifyListeners();
final result = await symptomsCheckerRepo.getClinicDetails(
categoryName: categoryName,
userSessionToken: currentSessionAuthToken,
);
result.fold(
(failure) async {
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
if (apiResponse.messageStatus == 1 && apiResponse.data != null) {
clinicDetailsList = apiResponse.data!;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse.data!);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Failed to fetch clinic details');
}
}
},
);
}
@override
void dispose() {
_tooltipTimer?.cancel();

@ -96,6 +96,8 @@ class TodoSectionRepoImp implements TodoSectionRepo {
}
}
ancillaryOrders.sort((a, b) => b.orderDate!.compareTo(a.orderDate!));
apiResponse = GenericApiModel<List<AncillaryOrderItem>>(
messageStatus: messageStatus,
statusCode: statusCode,

@ -45,21 +45,19 @@ class DefaultFirebaseOptions {
appId: '1:815750722565:android:62281cd3e5df4063',
messagingSenderId: '815750722565',
projectId: 'api-project-815750722565',
// databaseURL:
// 'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
storageBucket: 'api-project-815750722565.appspot.com',
databaseURL: 'https://api-project-815750722565.firebaseio.com',
storageBucket: 'api-project-815750722565.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA',
appId: '1:815750722565:ios:328ec247a81a2ca23c186c',
appId: '1:815750722565:ios:34ec03c09e02e21f3c186c',
messagingSenderId: '815750722565',
projectId: 'api-project-815750722565',
storageBucket: 'api-project-815750722565.appspot.com',
androidClientId:
'815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com',
iosClientId:
'815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com',
iosBundleId: 'com.HMG.HMG-Smartphone',
databaseURL: 'https://api-project-815750722565.firebaseio.com',
storageBucket: 'api-project-815750722565.firebasestorage.app',
androidClientId: '815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com',
iosBundleId: 'com.cloudsolutions.HMGPatientApp',
);
}
}

@ -941,6 +941,7 @@ abstract class LocaleKeys {
static const offline = 'offline';
static const videoCall = 'videoCall';
static const liveVideoCallWithHMGDoctors = 'liveVideoCallWithHMGDoctors';
static const liveAudioCallWithHMGDoctors = 'liveAudioCallWithHMGDoctors';
static const audioCall = 'audioCall';
static const phoneCall = 'phoneCall';
static const livePhoneCallWithHMGDoctors = 'livePhoneCallWithHMGDoctors';
@ -1563,5 +1564,14 @@ abstract class LocaleKeys {
static const noThanksIKnowTheClinic = 'noThanksIKnowTheClinic';
static const unableToSendOTP = 'unableToSendOTP';
static const loadingAIAnalysis = 'loadingAIAnalysis';
static const symptoms = 'symptoms';
static const insuranceInActive = 'insuranceInActive';
static const insuranceInActiveContactSupport = 'insuranceInActiveContactSupport';
static const updateAppNow = 'updateAppNow';
static const Dr = 'Dr';
static const reschedulingAppo = 'reschedulingAppo';
static const invalidEligibility = 'invalidEligibility';
static const invalidInsurance = 'invalidInsurance';
static const continueCash = 'continueCash';
}

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -76,12 +77,33 @@ Future<void> callAppStateInitializations() async {
: "3");
AppState appState = getIt.get<AppState>();
appState.setDeviceTypeID = deviceTypeId;
// Pass all uncaught "fatal" errors from the framework to Crashlytics
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
// Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
PlatformDispatcher.instance.onError = (error, stack) {
if (!kDebugMode) FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
}
Future<void> callInitializations() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
try {
// Attempt to get the default app. If it exists, this avoids the error.
await Firebase.app();
} catch (e) {
// If it doesn't exist, initialize it.
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
await AppDependencies.addDependencies();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
HttpOverrides.global = MyHttpOverrides();
@ -226,9 +248,16 @@ class MyApp extends StatelessWidget {
builder: (context, orientation, deviceType) {
// SizeConfig().init(constraints, orientation);
return MaterialApp(
title: 'Dr. AlHabib',
// title: 'Dr. AlHabib',
title: 'Dr. AlHabib Beta',
builder: (context, mchild) {
return MediaQuery(data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling, alwaysUse24HourFormat: true,), child: mchild!, );
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaler: TextScaler.noScaling,
alwaysUse24HourFormat: true,
),
child: mchild!,
);
},
showSemanticsDebugger: false,
debugShowCheckedModeBanner: false,

@ -99,6 +99,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? () {
contactUsViewModel.setSelectedFeedbackType(FeedbackType(id: 1, nameEN: "Complaint for appointment", nameAR: 'شكوى على موعد'));
contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel);
contactUsViewModel.setIsSendFeedbackTabSelected(true);
Navigator.of(context).push(
CustomPageRoute(
page: FeedbackPage(),
@ -111,9 +112,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppointmentDoctorCard(
renderWidgetForERDisplay: ((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) ||
(widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) ||
!Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID)),
// renderWidgetForERDisplay: ((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) ||
renderWidgetForERDisplay:
((widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) || !Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID)),
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onAskDoctorTap: () async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context));
@ -144,8 +145,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
});
},
onCancelTap: () async {
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr(context: context));
await myAppointmentsViewModel.cancelAppointment(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
@ -164,6 +163,18 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isDismissible: false,
isFullScreen: false,
);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err.toString()),
callBackFunc: () {},
title: "",
isCloseButtonVisible: true,
isDismissible: false,
isFullScreen: false,
);
});
var isEventAddedOrRemoved = await CalenderUtilsNew.instance.checkAndRemove( id:"${widget.patientAppointmentHistoryResponseModel.appointmentNo}", );
setState(() {
@ -532,7 +543,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
child: Utils.getErrorWidget(loadingText: LocaleKeys.noPrescriptionsForAppointment.tr(context: context)),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,

@ -290,6 +290,12 @@ class _MyDoctorsPageState extends State<MyDoctorsPage> {
clinicID: doctor?.clinicID ?? 0,
projectID: doctor?.projectID ?? 0,
doctorID: doctor?.doctorID ?? 0,
clinicName: doctor?.clinicName,
projectName: doctor?.projectName,
// nationalityFlagURL: doctor?.nationalityFlagURL,
name: doctor?.doctorName,
doctorImageURL: doctor?.doctorImageURL ?? doctor?.doctorImage,
speciality: doctor?.doctorSpeciality
));
LoaderBottomSheet.showLoader();
await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) {

@ -155,7 +155,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
myAppointmentsViewModel.getPatientAppointments(true, false);
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), callBackFunc: () async {
await myAppointmentsViewModel.getPatientAppointmentQueueDetails();
// await myAppointmentsViewModel.getPatientAppointmentQueueDetails();
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
context,
@ -163,11 +163,11 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
page: LandingNavigation(),
),
(r) => false);
Navigator.of(context).push(
CustomPageRoute(
page: AppointmentQueuePage(),
),
);
// Navigator.of(context).push(
// CustomPageRoute(
// page: AppointmentQueuePage(),
// ),
// );
}, isFullScreen: false);
},
onError: (error) {

@ -183,7 +183,7 @@ class AppointmentDoctorCard extends StatelessWidget {
)
: SizedBox.shrink();
} else {
return patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false
return patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {

@ -400,30 +400,30 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
),
);
}),
SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.pharmaLiveCare.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
"".toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
],
),
],
),
Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
],
).onPress(() {
openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
}),
// SizedBox(height: 16.h),
// Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
// SizedBox(height: 16.h),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Row(
// children: [
// Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
// SizedBox(width: 12.h),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// LocaleKeys.pharmaLiveCare.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
// "".toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
// ],
// ),
// ],
// ),
// Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
// ],
// ).onPress(() {
// openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
// }),
],
),
),

@ -110,7 +110,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain),
Utils.buildSvgWithAssets(icon: getLiveCareTypeIcon(immediateLiveCareVM.liveCareSelectedCallType), width: 32.h, height: 32.h, fit: BoxFit.contain),
SizedBox(width: 8.h),
getLiveCareType(context, immediateLiveCareVM.liveCareSelectedCallType).toText16(isBold: true),
],
@ -429,6 +429,19 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
// // }
// }
String getLiveCareTypeIcon(int callType) {
switch (callType) {
case 1:
return AppAssets.livecare_video;
case 2:
return AppAssets.livecare_audio;
case 3:
return AppAssets.livecare_phone;
default:
return AppAssets.livecare_video;
}
}
String getLiveCareType(BuildContext context, int callType) {
switch (callType) {
case 1:

@ -22,7 +22,7 @@ class SelectLiveCareCallType extends StatelessWidget {
return Column(
children: [
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.livecare_video,
LocaleKeys.videoCall.tr(context: context),
LocaleKeys.liveVideoCallWithHMGDoctors.tr(context: context),
).onPress(() {
@ -31,16 +31,16 @@ class SelectLiveCareCallType extends StatelessWidget {
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.livecare_audio,
LocaleKeys.audioCall.tr(context: context),
LocaleKeys.liveVideoCallWithHMGDoctors.tr(context: context),
LocaleKeys.liveAudioCallWithHMGDoctors.tr(context: context),
).onPress(() {
Navigator.of(context).pop();
immediateLiveCareViewModel.setLiveCareSelectedCallType(2);
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.livecare_phone,
LocaleKeys.phoneCall.tr(context: context),
LocaleKeys.livePhoneCallWithHMGDoctors.tr(context: context),
).onPress(() {

@ -11,6 +11,7 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/waiting_appointment/waiting_appointment_payment_page.dart';
@ -73,7 +74,7 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
Row(
children: [
Image.network(
bookAppointmentsViewModel.selectedDoctor.doctorImageURL!,
bookAppointmentsViewModel.selectedDoctor.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png",
width: 50.h,
height: 50.h,
fit: BoxFit.cover,
@ -83,15 +84,14 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.49,
child: "${bookAppointmentsViewModel.selectedDoctor.doctorTitle} ${bookAppointmentsViewModel.selectedDoctor.name}"
.toString()
.toText16(isBold: true, maxlines: 1),
),
"${bookAppointmentsViewModel.selectedDoctor.doctorTitle ?? LocaleKeys.Dr.tr(context: context)} ${bookAppointmentsViewModel.selectedDoctor.name}"
.toString()
.toText16(isBold: true, maxlines: 1),
SizedBox(width: 12.w),
Image.network(
bookAppointmentsViewModel.selectedDoctor.nationalityFlagURL!,
bookAppointmentsViewModel.selectedDoctor.nationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png",
width: 20.h,
height: 15.h,
fit: BoxFit.cover,
@ -242,11 +242,16 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingAppointmentShare.tr(context: context));
await bookAppointmentsViewModel.getWalkInPatientShareAppointment(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
Navigator.of(context).push(
CustomPageRoute(
page: WaitingAppointmentPaymentPage(),
),
);
if (bookAppointmentsViewModel.patientWalkInAppointmentShareResponseModel!.patientShareWithTax != 0 ||
bookAppointmentsViewModel.patientWalkInAppointmentShareResponseModel!.patientShareWithTax != 0.0) {
Navigator.of(context).push(
CustomPageRoute(
page: WaitingAppointmentPaymentPage(),
),
);
} else {
initiateBookAppointmentForWalkInNoPatientShare();
}
}, onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
@ -259,6 +264,49 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
});
}
void initiateBookAppointmentForWalkInNoPatientShare() async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingWaitingAppointment.tr(context: context));
await bookAppointmentsViewModel.insertSpecificAppointmentForWalkIn(onSuccess: (val) async {
String appointmentNo = val.data['AppointmentNo'].toString();
LoaderBottomSheet.hideLoader();
sendCheckInRequest(bookAppointmentsViewModel.waitingAppointmentNFCCode, appointmentNo, context);
});
}
void sendCheckInRequest(String scannedCode, String appointmentNo, BuildContext context) async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.processingCheckIn.tr(context: context));
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel = PatientAppointmentHistoryResponseModel(
appointmentNo: appointmentNo,
clinicID: bookAppointmentsViewModel.selectedDoctor.clinicID,
projectID: bookAppointmentsViewModel.selectedDoctor.projectID,
);
await myAppointmentsViewModel.sendCheckInNfcRequest(
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel,
scannedCode: scannedCode,
checkInType: 2,
onSuccess: (apiResponse) {
LoaderBottomSheet.hideLoader();
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
myAppointmentsViewModel.getPatientAppointments(true, false);
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: apiResponse.data["SuccessMsg"]), callBackFunc: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
}, isFullScreen: false);
},
onError: (error) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.error.tr(context: context), child: Utils.getErrorWidget(loadingText: error), callBackFunc: () {
Navigator.of(context).pop();
}, isFullScreen: false);
},
);
}
void initiateBookAppointment() async {
LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: LocaleKeys.bookingYourAppointment.tr(context: context));
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);

@ -640,6 +640,8 @@ class _WaitingAppointmentPaymentPageState extends State<WaitingAppointmentPaymen
checkInType: 2,
onSuccess: (apiResponse) {
LoaderBottomSheet.hideLoader();
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
myAppointmentsViewModel.getPatientAppointments(true, false);
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: apiResponse.data["SuccessMsg"]), callBackFunc: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
@ -658,6 +660,4 @@ class _WaitingAppointmentPaymentPageState extends State<WaitingAppointmentPaymen
},
);
}
void insertWalkInAppointment() async {}
}

@ -34,7 +34,7 @@ class ContactUs extends StatelessWidget {
return Column(
children: [
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.location,
LocaleKeys.findUs.tr(),
LocaleKeys.viewNearestHMGLocations.tr(),
).onPress(() {
@ -50,13 +50,14 @@ class ContactUs extends StatelessWidget {
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.feedbackFill,
LocaleKeys.feedback.tr(),
LocaleKeys.provideFeedbackOnServices.tr(),
).onPress(() {
contactUsViewModel.setSelectedFeedbackType(
FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'),
);
contactUsViewModel.setIsSendFeedbackTabSelected(true);
Navigator.pop(context);
Navigator.of(context).push(
CustomPageRoute(
@ -66,7 +67,7 @@ class ContactUs extends StatelessWidget {
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_location_icon,
AppAssets.ask_doctor_icon,
LocaleKeys.liveChat.tr(),
LocaleKeys.liveChatWithHMG.tr(),
).onPress(() {
@ -94,7 +95,7 @@ class ContactUs extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Utils.buildSvgWithAssets(icon: icon, width: 40.h, height: 40.h, fit: BoxFit.fill),
Utils.buildSvgWithAssets(icon: icon, width: 24.h, height: 24.h, fit: BoxFit.fill, iconColor: AppColors.textColor),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
@ -13,6 +14,7 @@ import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dar
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/contact_us/widgets/feedback_appointment_selection.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -24,6 +26,7 @@ import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
import 'dart:ui' as ui;
class FeedbackPage extends StatelessWidget {
FeedbackPage({super.key});
@ -34,10 +37,13 @@ class FeedbackPage extends StatelessWidget {
final TextEditingController subjectTextController = TextEditingController();
final TextEditingController messageTextController = TextEditingController();
late AppState appState;
@override
Widget build(BuildContext context) {
contactUsViewModel = Provider.of<ContactUsViewModel>(context, listen: false);
medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false);
appState = getIt.get<AppState>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Consumer<ContactUsViewModel>(builder: (context, contactUsVM, child) {
@ -67,11 +73,12 @@ class FeedbackPage extends StatelessWidget {
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
customBorder: BorderRadius.only(
topLeft: Radius.circular(24.h),
contactUsViewModel.isSendFeedbackTabSelected
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
customBorder: BorderRadius.only(
topLeft: Radius.circular(24.h),
topRight: Radius.circular(24.h),
),
hasShadow: true,
@ -126,7 +133,8 @@ class FeedbackPage extends StatelessWidget {
iconColor: AppColors.whiteColor,
iconSize: 20.h,
).paddingSymmetrical(24.h, 24.h),
),
)
: SizedBox.shrink(),
],
);
}),
@ -389,7 +397,99 @@ class FeedbackPage extends StatelessWidget {
],
);
} else {
return Container();
return getIt.get<AppState>().isAuthenticated
? Column(
children: [
SizedBox(height: 24.h),
ListView.builder(
itemCount: contactUsViewModel.isCOCItemsListLoading
? 4
: contactUsViewModel.cocItemsList.isEmpty
? 1
: contactUsViewModel.cocItemsList.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsetsGeometry.zero,
itemBuilder: (context, index) {
return contactUsViewModel.isCOCItemsListLoading
? LabResultItemView(
onTap: () {},
labOrder: null,
index: index,
isLoading: true,
)
: contactUsViewModel.cocItemsList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: appState.isArabic() ? contactUsViewModel.cocItemsList[index].statusAr : contactUsViewModel.cocItemsList[index].status,
// backgroundColor: AppColors.warningColorYellow,
backgroundColor: (contactUsViewModel.cocItemsList[index].statusId == 7 || contactUsViewModel.cocItemsList[index].statusId == 8)
? AppColors.primaryRedColor
: (contactUsViewModel.cocItemsList[index].statusId == 10 ||
contactUsViewModel.cocItemsList[index].statusId == 6 ||
contactUsViewModel.cocItemsList[index].statusId == 9)
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: AppColors.whiteColor,
),
SizedBox(height: 8.h),
"${LocaleKeys.requestID.tr(context: context)} ${contactUsViewModel.cocItemsList[index].itemID}".toText16(weight: FontWeight.bold),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 4.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(
labelText: contactUsViewModel.cocItemsList[index].date!.split(" ")[0],
icon: AppAssets.calendarGrey,
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
),
AppCustomChipWidget(
labelText: contactUsViewModel.cocItemsList[index].formType,
icon: AppAssets.ask_doctor_icon,
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
),
],
),
SizedBox(height: 8.h),
"${contactUsViewModel.cocItemsList[index].cOCTitle}"
.toText16(weight: FontWeight.bold, fontFamily: Utils.isArabicText(contactUsViewModel.cocItemsList[index].cOCTitle ?? "") ? "GESSTwo" : "Poppins"),
SizedBox(height: 8.h),
"${contactUsViewModel.cocItemsList[index].detail}".toText14(
weight: FontWeight.w500,
color: AppColors.textColorLight,
fontFamily: Utils.isArabicText(contactUsViewModel.cocItemsList[index].detail ?? "") ? "GESSTwo" : "Poppins"),
],
),
).paddingOnly(bottom: 16.h),
),
),
),
)
: Utils.getNoDataWidget(context);
}),
],
)
: Utils.getNoDataWidget(context);
}
}
}

@ -105,7 +105,9 @@ class ErOnlineCheckinHome extends StatelessWidget {
);
});
},
onError: (err) {});
onError: (err) {
LoaderBottomSheet.hideLoader();
});
});
}, onCancel: () {});
});

@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/features/emergency_services/emergency_servic
import 'package:hmg_patient_app_new/features/payfort/models/apple_pay_request_insert_model.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
@ -445,7 +446,14 @@ class _ErOnlineCheckinPaymentPageState extends State<ErOnlineCheckinPaymentPage>
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getSuccessWidget(loadingText: LocaleKeys.erAppointmentBookedSuccess.tr(context: context)),
callBackFunc: () {},
callBackFunc: () {
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
},
isFullScreen: false,
isCloseButtonVisible: true,
);
@ -458,7 +466,14 @@ class _ErOnlineCheckinPaymentPageState extends State<ErOnlineCheckinPaymentPage>
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)),
callBackFunc: () {},
callBackFunc: () {
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
},
isFullScreen: false,
isCloseButtonVisible: true,
);

@ -53,14 +53,7 @@ class ServicesPage extends StatelessWidget {
late MedicalFileViewModel medicalFileViewModel;
late final List<HmgServicesComponentModel> hmgServices = [
HmgServicesComponentModel(
11,
LocaleKeys.emergencyServices.tr(),
"",
AppAssets.emergency_services_icon,
bgColor: AppColors.primaryRedColor,
true,
route: null, onTap: () async {
HmgServicesComponentModel(11, LocaleKeys.emergencyServices.tr(), "", AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () async {
if (getIt.get<AppState>().isAuthenticated) {
getIt.get<EmergencyServicesViewModel>().flushData();
getIt.get<EmergencyServicesViewModel>().getTransportationOrders(
@ -88,8 +81,7 @@ class ServicesPage extends StatelessWidget {
true,
route: AppRoutes.bookAppointmentPage,
),
HmgServicesComponentModel(
5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async {
HmgServicesComponentModel(5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async {
if (getIt.get<AppState>().isAuthenticated) {
getIt.get<NavigationService>().pushPageRoute(AppRoutes.comprehensiveCheckupPage);
} else {
@ -141,8 +133,7 @@ class ServicesPage extends StatelessWidget {
);
},
),
HmgServicesComponentModel(
11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async {
HmgServicesComponentModel(11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async {
if (getIt.get<AppState>().isAuthenticated) {
getIt.get<NavigationService>().pushPageRoute(AppRoutes.eReferralPage);
} else {
@ -415,19 +406,19 @@ class ServicesPage extends StatelessWidget {
? CustomButton(
height: 40.h,
icon: AppAssets.recharge_icon,
iconSize: 24.w,
iconColor: AppColors.infoColor,
textColor: AppColors.infoColor,
text: LocaleKeys.recharge.tr(),
borderWidth: 0.w,
fontWeight: FontWeight.w500,
borderColor: Colors.transparent,
backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08),
padding: EdgeInsets.all(8.w),
fontSize: 14.f,
onPressed: () {
Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage()));
},
iconSize: 24.w,
iconColor: AppColors.infoColor,
textColor: AppColors.infoColor,
text: LocaleKeys.recharge.tr(),
borderWidth: 0.w,
fontWeight: FontWeight.w500,
borderColor: Colors.transparent,
backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08),
padding: EdgeInsets.all(8.w),
fontSize: 14.f,
onPressed: () {
Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage()));
},
)
: SizedBox.shrink(),
],
@ -467,60 +458,60 @@ class ServicesPage extends StatelessWidget {
getIt.get<AppState>().isAuthenticated
? Wrap(
spacing: -12.h,
// runSpacing: 0.h,
children: [
Utils.buildImgWithAssets(
icon: AppAssets.babyGirlImg,
height: 32.h,
width: 32.w,
border: 1,
fit: BoxFit.contain,
borderRadius: 50.r,
),
Utils.buildImgWithAssets(
icon: AppAssets.femaleImg,
height: 32.h,
width: 32.w,
border: 1,
borderRadius: 50.r,
fit: BoxFit.contain,
),
Utils.buildImgWithAssets(
icon: AppAssets.maleImg,
height: 32.h,
width: 32.w,
border: 1,
borderRadius: 50.r,
fit: BoxFit.contain,
),
],
// runSpacing: 0.h,
children: [
Utils.buildImgWithAssets(
icon: AppAssets.babyGirlImg,
height: 32.h,
width: 32.w,
border: 1,
fit: BoxFit.contain,
borderRadius: 50.r,
),
Utils.buildImgWithAssets(
icon: AppAssets.femaleImg,
height: 32.h,
width: 32.w,
border: 1,
borderRadius: 50.r,
fit: BoxFit.contain,
),
Utils.buildImgWithAssets(
icon: AppAssets.maleImg,
height: 32.h,
width: 32.w,
border: 1,
borderRadius: 50.r,
fit: BoxFit.contain,
),
],
)
: LocaleKeys.loginToViewMedicalFile.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2),
Spacer(),
getIt.get<AppState>().isAuthenticated
? CustomButton(
height: 40.h,
icon: AppAssets.add_icon,
iconSize: 24.h,
iconColor: AppColors.primaryRedColor,
textColor: AppColors.primaryRedColor,
text: LocaleKeys.addMember.tr(),
borderWidth: 0.w,
fontWeight: FontWeight.w500,
borderColor: Colors.transparent,
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08),
padding: EdgeInsets.all(8.w),
fontSize: 14.f,
onPressed: () {
DialogService dialogService = getIt.get<DialogService>();
medicalFileViewModel.clearAuthValues();
dialogService.showAddFamilyFileSheet(
label: LocaleKeys.addFamilyMember.tr(),
message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(),
onVerificationPress: () {
medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms);
});
},
icon: AppAssets.add_icon,
iconSize: 24.h,
iconColor: AppColors.primaryRedColor,
textColor: AppColors.primaryRedColor,
text: LocaleKeys.addMember.tr(),
borderWidth: 0.w,
fontWeight: FontWeight.w500,
borderColor: Colors.transparent,
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08),
padding: EdgeInsets.all(8.w),
fontSize: 14.f,
onPressed: () {
DialogService dialogService = getIt.get<DialogService>();
medicalFileViewModel.clearAuthValues();
dialogService.showAddFamilyFileSheet(
label: LocaleKeys.addFamilyMember.tr(),
message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(),
onVerificationPress: () {
medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms);
});
},
)
: SizedBox.shrink(),
],
@ -700,6 +691,58 @@ class ServicesPage extends StatelessWidget {
}),
)
],
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 12.h,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor),
SizedBox(width: 8.w),
Expanded(child: LocaleKeys.termsConditoins.tr().toText14(weight: FontWeight.w500))
],
),
),
).onPress(() {
Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx',
);
}),
),
SizedBox(width: 16.w),
Expanded(
child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 12.h,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor),
SizedBox(width: 8.w),
Expanded(child: LocaleKeys.privacyPolicy.tr().toText14(weight: FontWeight.w500))
],
),
),
).onPress(() {
Utils.openWebView(
url: 'https://hmg.com/en/Pages/Privacy.aspx',
);
}),
)
],
)
],
).paddingSymmetrical(24.w, 0),

@ -0,0 +1,96 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:in_app_update/in_app_update.dart';
import 'package:lottie/lottie.dart';
class AppUpdatePage extends StatelessWidget {
AppUpdatePage({super.key, required this.appUpdateMessage});
String appUpdateMessage;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.whiteColor,
body: Column(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.all(24.h),
child: Column(
children: [
SizedBox(height: 120.h),
Align(
alignment: Alignment.topCenter,
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic() ? true : false,
child: Lottie.asset(AppAnimations.onboarding_1,
repeat: true, reverse: false, frameRate: FrameRate(60), width: MediaQuery.sizeOf(context).width - 50.w, height: MediaQuery.sizeOf(context).width - 50.w),
),
),
SizedBox(height: 50.h),
appUpdateMessage.toText16(weight: FontWeight.w500),
],
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
hasShadow: true,
),
child: CustomButton(
text: LocaleKeys.updateAppNow.tr(context: context),
onPressed: () {
openAppUpdateLink();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 56.h,
),
).paddingAll(24.h),
],
),
);
}
openAppUpdateLink() {
if (Platform.isAndroid) {
// _launchURL("https://play.google.com/store/apps/details?id=com.ejada.hmg");
InAppUpdate.checkForUpdate().then((info) {
print("checkForUpdate!!!");
print(info.toString());
if (info.immediateUpdateAllowed) {
print("Immediate Allowed!!!");
InAppUpdate.performImmediateUpdate().then((value) {}).catchError((e) => print(e.toString()));
}
}).catchError((e) {
print(e.toString());
Utils.openWebView(
url: "https://play.google.com/store/apps/details?id=com.ejada.hmg",
);
});
}
if (Platform.isIOS) {
Utils.openWebView(
url: "https://itunes.apple.com/app/id733503978",
);
}
}
}

@ -460,7 +460,7 @@ class _LandingPageState extends State<LandingPage> {
return emergencyServicesVM.patientHasAdvanceERBalance
? Column(
children: [
SizedBox(height: 4.h),
SizedBox(height: 16.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
@ -490,12 +490,15 @@ class _LandingPageState extends State<LandingPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true),
Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor,
width: 20.h,
height: 15.h,
fit: BoxFit.contain,
Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor,
width: 20.h,
height: 15.h,
fit: BoxFit.contain,
),
),
],
),
@ -509,10 +512,10 @@ class _LandingPageState extends State<LandingPage> {
SizedBox(height: 12.h),
],
)
: SizedBox(height: 12.h);
: SizedBox(height: 0.h);
},
),
SizedBox(height: 24.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [

@ -52,36 +52,36 @@ class HabibWalletCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
LocaleKeys.habibWallet.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Container(
height: 40.h,
width: 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 8.h,
),
child: Padding(
padding: EdgeInsets.all(8.h),
child: Utils.buildSvgWithAssets(
icon: AppAssets.show_icon,
width: 12.h,
height: 12.h,
fit: BoxFit.contain,
),
),
),
],
),
// Container(
// height: 40.h,
// width: 40.h,
// decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
// color: AppColors.textColor,
// borderRadius: 8.h,
// ),
// child: Padding(
// padding: EdgeInsets.all(8.h),
// child: Utils.buildSvgWithAssets(
// icon: AppAssets.show_icon,
// width: 12.h,
// height: 12.h,
// fit: BoxFit.contain,
// ),
// ),
// ),
// ],
// ),
SizedBox(height: 4.h),
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.saudi_riyal_icon,
iconColor: AppColors.dividerColor,
iconColor: AppColors.inputLabelTextColor,
width: 24.h,
height: 24.h,
fit: BoxFit.contain,

@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
@ -16,6 +17,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
class PatientInsuranceCard extends StatelessWidget {
PatientInsuranceCard({super.key, required this.insuranceCardDetailsModel, required this.isInsuranceExpired});
@ -49,19 +51,73 @@ class PatientInsuranceCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.45, child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true)),
width: MediaQuery.of(context).size.width * 0.4,
child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.clip)),
LocaleKeys.policyNumber.tr(namedArgs: {'number': insuranceCardDetailsModel.insurancePolicyNo ?? ''}, context: context).toText12(isBold: true, color: AppColors.lightGrayColor),
],
),
AppCustomChipWidget(
icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon,
labelText: isInsuranceExpired ? LocaleKeys.insuranceExpired.tr(context: context) : LocaleKeys.insuranceActive.tr(context: context),
iconColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
textColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
iconSize: 12,
backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h),
),
icon: insuranceViewModel.isInsuranceExpired
? AppAssets.cancel_circle_icon
: insuranceViewModel.isInsuranceActive
? AppAssets.insurance_active_icon
: AppAssets.alertSquare,
labelText: insuranceViewModel.isInsuranceExpired
? LocaleKeys.insuranceExpired.tr(context: context)
: insuranceViewModel.isInsuranceActive
? LocaleKeys.insuranceActive.tr(context: context)
: LocaleKeys.insuranceInActive.tr(context: context),
iconColor: insuranceViewModel.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceViewModel.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: insuranceViewModel.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceViewModel.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
iconSize: 12.w,
deleteIcon: insuranceViewModel.isInsuranceActive ? null : AppAssets.forward_chevron_icon,
deleteIconColor: AppColors.warningColorYellow,
deleteIconHasColor: true,
onChipTap: () {
if (!insuranceViewModel.isInsuranceActive) {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context),
confirmText: LocaleKeys.contactUs.tr(context: context),
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(context);
},
onConfirmTap: () async {
launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
},
backgroundColor: insuranceViewModel.isInsuranceExpired
? AppColors.primaryRedColor.withOpacity(0.1)
: insuranceViewModel.isInsuranceActive
? AppColors.successColor.withOpacity(0.1)
: AppColors.warningColorYellow.withOpacity(0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceViewModel.isInsuranceActive ? 6.w : 0.w),
).toShimmer2(isShow: insuranceViewModel.isInsuranceLoading),
// AppCustomChipWidget(
// icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon,
// labelText: isInsuranceExpired ? LocaleKeys.insuranceExpired.tr(context: context) : LocaleKeys.insuranceActive.tr(context: context),
// iconColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
// textColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
// iconSize: 12,
// backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1),
// labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h),
// ),
],
),
SizedBox(height: 12.h),

File diff suppressed because one or more lines are too long

@ -14,7 +14,7 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/expandable_list_widget.dart';
import 'package:provider/provider.dart';
import '../../features/lab/models/resp_models/ai_overview_labresults_by_ai_model.dart';
import '../../../features/lab/models/resp_models/ai_overview_labresults_by_ai_model.dart';
class LabAiAnalysisDetailedPage extends StatefulWidget {
const LabAiAnalysisDetailedPage({super.key});
@ -314,6 +314,16 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
defaultTrailingIcon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w, iconColor: AppColors.textColor),
),
).paddingSymmetrical(16.w, 0.0),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.info_outline, color: AppColors.greyTextColor, size: 20.r),
SizedBox(width: 8.w),
Expanded(
child: ("${LocaleKeys.disclaimer.tr()}:${LocaleKeys.thisAboveInfo.tr()}").toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w400),
),
],
).paddingSymmetrical(16.w, 16.h)
],
);
},

@ -33,6 +33,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/my_invoices/my_invoices_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/active_medication/active_medication_page.dart';
import 'package:hmg_patient_app_new/presentation/allergies/allergies_list_page.dart';
@ -78,6 +79,7 @@ import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../features/active_prescriptions/active_prescriptions_view_model.dart';
import '../prescriptions/prescription_detail_page.dart';
@ -286,14 +288,58 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
),
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return AppCustomChipWidget(
icon: insuranceVM.isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon,
labelText: insuranceVM.isInsuranceExpired ? LocaleKeys.insuranceExpired.tr(context: context) : LocaleKeys.insuranceActive.tr(context: context),
iconColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
textColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
icon: insuranceVM.isInsuranceExpired
? AppAssets.cancel_circle_icon
: insuranceVM.isInsuranceActive
? AppAssets.insurance_active_icon
: AppAssets.alertSquare,
labelText: insuranceVM.isInsuranceExpired
? LocaleKeys.insuranceExpired.tr(context: context)
: insuranceVM.isInsuranceActive
? LocaleKeys.insuranceActive.tr(context: context)
: LocaleKeys.insuranceInActive.tr(context: context),
iconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
iconSize: 12.w,
backgroundColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
);
deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon,
deleteIconColor: AppColors.warningColorYellow,
deleteIconHasColor: true,
onChipTap: () {
if (!insuranceVM.isInsuranceActive) {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!),
navigationService.navigatorKey.currentContext!,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context),
confirmText: LocaleKeys.contactUs.tr(context: context),
isShowActionButtons: true,
onCancelTap: () {
navigationService.pop();
},
onConfirmTap: () async {
launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor.withOpacity(0.1)
: insuranceVM.isInsuranceActive
? AppColors.successColor.withOpacity(0.1)
: AppColors.warningColorYellow.withOpacity(0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w),
).toShimmer2(isShow: insuranceVM.isInsuranceLoading);
}),
],
),
@ -1176,6 +1222,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
isLargeText: true,
iconSize: 36.w,
).onPress(() {
getIt.get<TodoSectionViewModel>().setIsAncillaryOrdersNeedReloading(true);
Navigator.of(context).push(
CustomPageRoute(
page: ToDoPage(),

@ -30,6 +30,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
@ -197,9 +198,11 @@ class ProfileSettingsState extends State<ProfileSettings> {
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false);
}, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"),
1.divider,
actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {}),
1.divider,
actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true),
actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {
openAppSettings();
}),
// 1.divider,
// actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true),
],
),
),
@ -228,11 +231,11 @@ class ProfileSettingsState extends State<ProfileSettings> {
child: Column(
children: [
actionItem(AppAssets.call_fill, LocaleKeys.contactUs.tr(context: context), () {
launchUrl(Uri.parse("tel://" + "+966 11 525 9999"));
}, trailingLabel: "011 525 9999"),
1.divider,
actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"),
launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
}, trailingLabel: "92 006 6666"),
1.divider,
// actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"),
// 1.divider,
actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () {
if (Platform.isAndroid) {
Utils.openWebView(
@ -366,61 +369,66 @@ class FamilyCardWidget extends StatelessWidget {
labelText: "Blood: ${appState.getAuthenticatedUser()!.bloodGroup ?? ""}",
iconColor: AppColors.primaryRedColor)
: SizedBox(),
Selector<InsuranceViewModel, ({bool isEmpty, int? patientID, bool isLoading, String? cardValidTo})>(
selector: (context, insuranceVM) => (
isEmpty: insuranceVM.patientInsuranceList.isEmpty,
patientID: insuranceVM.patientInsuranceList.isNotEmpty ? insuranceVM.patientInsuranceList.first.patientID : null,
isLoading: insuranceVM.isInsuranceLoading,
cardValidTo: insuranceVM.patientInsuranceList.isNotEmpty ? insuranceVM.patientInsuranceList.first.cardValidTo : null
),
builder: (context, data, child) {
if (data.isEmpty) {
return const SizedBox();
} else if (profile.responseId != data.patientID) {
return SizedBox();
}
final isLoading = data.isLoading;
final isExpired = !isLoading && DateTime.now().isAfter(DateUtil.convertStringToDate(data.cardValidTo));
final String icon;
final String labelText;
final Color iconColor;
final Color backgroundColor;
if (isLoading) {
icon = AppAssets.cancel_circle_icon;
labelText = LocaleKeys.insurance.tr(context: context);
iconColor = AppColors.primaryRedColor;
backgroundColor = AppColors.primaryRedColor;
} else if (isExpired) {
icon = AppAssets.cancel_circle_icon;
labelText = LocaleKeys.insuranceExpired.tr(context: context);
iconColor = AppColors.primaryRedColor;
backgroundColor = AppColors.primaryRedColor.withValues(alpha: 0.15);
} else {
icon = AppAssets.insurance_active_icon;
labelText = LocaleKeys.insuranceActive.tr(context: context);
iconColor = AppColors.successColor;
backgroundColor = AppColors.successColor.withValues(alpha: 0.15);
}
return AppCustomChipWidget(
icon: icon,
labelText: labelText,
iconColor: iconColor,
iconSize: 12.w,
backgroundColor: backgroundColor,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 8.w),
// padding: EdgeInsets.zero,
).toShimmer2(isShow: isLoading);
},
)
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return AppCustomChipWidget(
icon: insuranceVM.isInsuranceExpired
? AppAssets.cancel_circle_icon
: insuranceVM.isInsuranceActive
? AppAssets.insurance_active_icon
: AppAssets.alertSquare,
labelText: insuranceVM.isInsuranceExpired
? LocaleKeys.insuranceExpired.tr(context: context)
: insuranceVM.isInsuranceActive
? LocaleKeys.insuranceActive.tr(context: context)
: LocaleKeys.insuranceInActive.tr(context: context),
iconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
iconSize: 12.w,
deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon,
deleteIconColor: AppColors.warningColorYellow,
deleteIconHasColor: true,
onChipTap: () {
if (!insuranceVM.isInsuranceActive) {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context),
confirmText: LocaleKeys.contactUs.tr(context: context),
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(context);
},
onConfirmTap: () async {
launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor.withOpacity(0.1)
: insuranceVM.isInsuranceActive
? AppColors.successColor.withOpacity(0.1)
: AppColors.warningColorYellow.withOpacity(0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w),
).toShimmer2(isShow: insuranceVM.isInsuranceLoading);
}),
],
),
),
],
).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 0.h),
).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 8.h),
1.divider.paddingSymmetrical(16.w, 0.h),
_buildActionButton(appState),
],

@ -310,8 +310,8 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
),
),
AppCustomChipWidget(
labelText: model.isSortByClinic ? (order.clinicDescription ?? '') : (order.projectName ?? ''),
),
labelText: model.isSortByClinic ? (order.projectName ?? '') : (order.clinicDescription ?? ''),
),
],
),
SizedBox(height: 12.h),

@ -8,20 +8,32 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/condition_card.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';
import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
class PossibleConditionsPage extends StatelessWidget {
const PossibleConditionsPage({super.key});
PossibleConditionsPage({super.key});
late SymptomsCheckerViewModel symptomsCheckerViewModel;
late BookAppointmentsViewModel bookAppointmentsViewModel;
late AppointmentViaRegionViewmodel regionalViewModel;
Widget _buildLoadingShimmer() {
return ListView.separated(
@ -80,8 +92,20 @@ class PossibleConditionsPage extends StatelessWidget {
condition: condition,
symptoms: symptoms,
onActionPressed: () {
dialogService.showErrorBottomSheet(
message: 'icd10 Code is ${condition.conditionDetails?.icd10Code}. We need to get the clinics mapped against this code.',
LoaderBottomSheet.showLoader();
symptomsCheckerViewModel.getClinicConditionsFromCategory(
categoryName: (condition.conditionDetails!.category!.name) ?? "Other",
onSuccess: (value) {
LoaderBottomSheet.hideLoader();
print(symptomsCheckerViewModel.clinicDetailsList.first.clinicID);
initiateBookAppointmentFlow(context);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
dialogService.showErrorBottomSheet(
message: err.toString(),
);
},
);
},
);
@ -194,6 +218,9 @@ class PossibleConditionsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
symptomsCheckerViewModel = context.read<SymptomsCheckerViewModel>();
bookAppointmentsViewModel = context.read<BookAppointmentsViewModel>();
regionalViewModel = context.read<AppointmentViaRegionViewmodel>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
@ -202,7 +229,6 @@ class PossibleConditionsPage extends StatelessWidget {
context: context,
onConfirm: () {
context.pop();
final SymptomsCheckerViewModel symptomsCheckerViewModel = context.read<SymptomsCheckerViewModel>();
symptomsCheckerViewModel.reset(); // Clear all symptoms checker data
final navigationService = getIt.get<NavigationService>();
// navigationService.replaceAllRoutesAndNavigateToLanding();
@ -230,4 +256,102 @@ class PossibleConditionsPage extends StatelessWidget {
),
);
}
initiateBookAppointmentFlow(BuildContext context) {
bookAppointmentsViewModel.getLocation();
bookAppointmentsViewModel.setSelectedClinic(GetClinicsListResponseModel(
clinicID: symptomsCheckerViewModel.clinicDetailsList.first.clinicID,
clinicDescription: symptomsCheckerViewModel.clinicDetailsList.first.category,
clinicDescriptionN: symptomsCheckerViewModel.clinicDetailsList.first.categoryAR,
));
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
var bottomSheetType = RegionBottomSheetType.FOR_CLINIIC;
openRegionListBottomSheet(context, bottomSheetType);
}
getTitle(AppointmentViaRegionViewmodel data, BuildContext context) {
if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600);
} else {
return Transform.flip(
flipX: data.isArabic ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
iconColor: Color(0xff2B353E),
fit: BoxFit.contain,
),
).onPress(() {
data.handleBackPress();
});
}
}
void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) {
bookAppointmentsViewModel.setProjectID(null);
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data, context)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (context, data, __) {
return getRegionalSelectionWidget(data, context);
}), callBackFunc: () {});
}
Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data, BuildContext context) {
if (data.bottomSheetState == AppointmentViaRegionState.REGION_SELECTION) {
return RegionBottomSheetBody();
}
if (data.bottomSheetState == AppointmentViaRegionState.TYPE_SELECTION) {
bookAppointmentsViewModel.resetFilterList();
return FacilityTypeSelectionWidget(
selectedRegion: data.selectedRegionId ?? "",
);
}
if (data.bottomSheetState == AppointmentViaRegionState.HOSPITAL_SELECTION) {
return HospitalBottomSheetBody(
searchText: data.searchController,
displayList: data.displayList,
onFacilityClicked: (value) {
data.setSelectedFacility(value);
data.getDisplayList();
},
onHospitalClicked: (hospital) {
regionalViewModel.setHospitalModel(hospital);
if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.CLINIC_SELECTION);
regionalViewModel.handleLastStepForRegion();
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
regionalViewModel.handleLastStepForClinic();
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
var appointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
regionalViewModel.handleLastStepForClinicForDentalAndLaser(appointmentsViewModel.selectedClinic.clinicID ?? -1);
}
},
onHospitalSearch: (value) {
data.searchHospitals(value ?? "");
},
selectedFacility: data.selectedFacility,
hmcCount: data.hmcCount,
hmgCount: data.hmgCount,
);
}
if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) {
//if the region screen is opened for the dental clinic then the project id will be in the hospital list as the list is formed form the get project api
var id = "";
if (data.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
id = regionalViewModel.selectedHospital?.hospitalList.first.iD?.toString() ?? "";
} else {
id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first.projectID?.toString() ?? "";
}
bookAppointmentsViewModel.setProjectID(id);
return SizedBox.shrink();
} else {
return SizedBox.shrink();
}
return SizedBox.shrink();
}
}

@ -352,43 +352,44 @@ class _CallScreenState extends State<CallScreen> {
ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf();
if (data['status'] == RecordingStatus.Start) {
if (mySelf != null && !mySelf.isHost!) {
showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
content: const Text('The session is being recorded.'),
actions: <Widget>[
TextButton(
onPressed: () async {
await zoom.acceptRecordingConsent();
if (context.mounted) {
Navigator.pop(context);
}
;
},
child: const Text('accept'),
),
TextButton(
onPressed: () async {
String currentConsentType = await zoom.getRecordingConsentType();
if (currentConsentType == ConsentType.ConsentType_Individual) {
await zoom.declineRecordingConsent();
Navigator.pop(context);
} else {
await zoom.declineRecordingConsent();
zoom.leaveSession(false);
if (!context.mounted) return;
Navigator.popAndPushNamed(
context,
"Join",
arguments: JoinArguments(args.isJoin, sessionName.value, sessionPassword.value, args.displayName, args.sessionIdleTimeoutMins, args.role),
);
}
},
child: const Text('decline'),
),
],
),
);
await zoom.acceptRecordingConsent();
// showDialog<String>(
// context: context,
// builder: (BuildContext context) => AlertDialog(
// content: const Text('The session is being recorded.'),
// actions: <Widget>[
// TextButton(
// onPressed: () async {
// await zoom.acceptRecordingConsent();
// if (context.mounted) {
// Navigator.pop(context);
// }
// ;
// },
// child: const Text('accept'),
// ),
// TextButton(
// onPressed: () async {
// String currentConsentType = await zoom.getRecordingConsentType();
// if (currentConsentType == ConsentType.ConsentType_Individual) {
// await zoom.declineRecordingConsent();
// Navigator.pop(context);
// } else {
// await zoom.declineRecordingConsent();
// zoom.leaveSession(false);
// if (!context.mounted) return;
// Navigator.popAndPushNamed(
// context,
// "Join",
// arguments: JoinArguments(args.isJoin, sessionName.value, sessionPassword.value, args.displayName, args.sessionIdleTimeoutMins, args.role),
// );
// }
// },
// child: const Text('decline'),
// ),
// ],
// ),
// );
}
isRecordingStarted.value = true;
} else {
@ -1745,11 +1746,11 @@ class _CallScreenState extends State<CallScreen> {
iconSize: circleButtonSize,
tooltip: isMuted.value == true ? "Unmute" : "Mute",
),
IconButton(
onPressed: onPressShare,
icon: isSharing.value ? Image.asset("assets/images/png/zoom/share-off@2x.png") : Image.asset("assets/images/png/zoom/share-on@2x.png"),
iconSize: circleButtonSize,
),
// IconButton(
// onPressed: onPressShare,
// icon: isSharing.value ? Image.asset("assets/images/png/zoom/share-off@2x.png") : Image.asset("assets/images/png/zoom/share-on@2x.png"),
// iconSize: circleButtonSize,
// ),
IconButton(
onPressed: onPressVideo,
iconSize: circleButtonSize,
@ -1771,35 +1772,35 @@ class _CallScreenState extends State<CallScreen> {
],
),
)),
Container(
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 40, top: 10),
alignment: Alignment.bottomCenter,
child: SizedBox(
height: MediaQuery.of(context).viewInsets.bottom == 0 ? 65 : MediaQuery.of(context).viewInsets.bottom + 18,
child: TextField(
maxLines: 1,
textAlign: TextAlign.left,
style: TextStyle(color: chatTextColor),
cursorColor: chatTextColor,
textAlignVertical: TextAlignVertical.center,
controller: chatMessageController,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 16, top: 10, bottom: 10, right: 16),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1, color: chatTextColor), //<-- SEE HERE
),
hintText: 'Type your message here...',
hintStyle: TextStyle(
fontSize: 14.0,
color: chatTextColor,
),
),
onSubmitted: (String str) {
sendChatMessage(str);
},
),
),
),
// Container(
// margin: const EdgeInsets.only(left: 16, right: 16, bottom: 40, top: 10),
// alignment: Alignment.bottomCenter,
// child: SizedBox(
// height: MediaQuery.of(context).viewInsets.bottom == 0 ? 65 : MediaQuery.of(context).viewInsets.bottom + 18,
// child: TextField(
// maxLines: 1,
// textAlign: TextAlign.left,
// style: TextStyle(color: chatTextColor),
// cursorColor: chatTextColor,
// textAlignVertical: TextAlignVertical.center,
// controller: chatMessageController,
// decoration: InputDecoration(
// contentPadding: const EdgeInsets.only(left: 16, top: 10, bottom: 10, right: 16),
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(width: 1, color: chatTextColor), //<-- SEE HERE
// ),
// hintText: 'Type your message here...',
// hintStyle: TextStyle(
// fontSize: 14.0,
// color: chatTextColor,
// ),
// ),
// onSubmitted: (String str) {
// sendChatMessage(str);
// },
// ),
// ),
// ),
Container(
alignment: Alignment.bottomLeft,
margin: const EdgeInsets.only(bottom: 120),

@ -103,7 +103,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.visaOrMastercard.tr(context: context).toText16(isBold: true).toShimmer2(isShow: todoVM.isProcessingPayment),
Image.asset(AppAssets.mada, width: 50.h, height: 50.h),
SizedBox(height: 16.h),
LocaleKeys.mada.tr(context: context).toText16(isBold: true).toShimmer2(isShow: todoVM.isProcessingPayment),
],
@ -468,86 +468,43 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
languageID: appState.isArabic() ? 1 : 2,
onSuccess: (response) {
LoaderBottomSheet.hideLoader();
final invoiceNo = response['AncillaryOrderInvoiceList']?[0]?['InvoiceNo'];
_showSuccessDialog(invoiceNo);
},
onError: (error) {
LoaderBottomSheet.hideLoader();
todoSectionViewModel.setProcessingPayment(false);
Utils.showToast(error);
showCommonBottomSheetWithoutHeight(context,
child: Utils.getErrorWidget(loadingText: error.toString()), isCloseButtonVisible: true, isDismissible: true, isFullScreen: false, callBackFunc: () {});
},
);
}
void _showSuccessDialog(dynamic invoiceNo) {
todoSectionViewModel.setProcessingPayment(false);
log("Ancillary order payment successful! Invoice #: $invoiceNo");
// Show success message and navigate
Utils.showToast("Payment successful! Invoice #: $invoiceNo");
// Utils.showToast("Payment successful! Invoice #: $invoiceNo");
// Navigate back to home after a short delay
Future.delayed(Duration(seconds: 1), () {
showCommonBottomSheetWithoutHeight(
context,
child: Column(
children: [
Row(
children: [
LocaleKeys.hereIsYourInvoiceNumber.tr(context: context).toText14(
color: AppColors.textColorLight,
weight: FontWeight.w500,
),
SizedBox(width: 4.w),
("12345").toText16(isBold: true),
],
),
SizedBox(height: 24.h),
Row(
children: [
Expanded(
child: CustomButton(
height: 56.h,
text: LocaleKeys.ok.tr(context: context),
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
),
),
],
),
],
),
// title: LocaleKeys.paymentCompletedSuccessfully.tr(context: context),
titleWidget: Utils.getSuccessWidget(loadingText: LocaleKeys.paymentCompletedSuccessfully.tr(context: context)),
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false,
);
// Future.delayed(Duration(seconds: 1), () {
showCommonBottomSheetWithoutHeight(context,
child: Utils.getSuccessWidget(loadingText: "${LocaleKeys.paymentCompletedSuccessfully.tr(context: context)}, ${LocaleKeys.hereIsYourInvoiceNumber.tr(context: context)}$invoiceNo"),
isCloseButtonVisible: true,
isDismissible: true,
isFullScreen: false, callBackFunc: () {
// Pop until we reach the LandingPage
todoSectionViewModel.setIsAncillaryOrdersNeedReloading(true);
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
});
// });
}
_startApplePay() async {
showCommonBottomSheet(
context,
child: Utils.getLoadingWidget(),
callBackFunc: (str) {},
title: "",
height: ResponsiveExtension.screenHeight * 0.3,
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false,
);
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingApplePayDetails.tr(context: context));
final user = appState.getAuthenticatedUser();
transID = Utils.getAdvancePaymentTransID(widget.projectID, user!.patientId!);
@ -604,7 +561,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
await payfortViewModel.applePayRequestInsert(applePayInsertRequest: applePayInsertRequest);
} catch (error) {
log("Apple Pay Insert Request Failed: $error");
Navigator.of(context).pop();
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: LocaleKeys.failedToInitializeApplePay.tr(context: context)),
@ -627,7 +584,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
log("failureResult: ${failureResult.message.toString()}");
Navigator.of(context).pop();
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: failureResult.message.toString()),
@ -637,7 +594,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
);
},
onSucceeded: (successResult) async {
Navigator.of(context).pop();
LoaderBottomSheet.hideLoader();
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";
_checkPaymentStatus();

@ -14,6 +14,7 @@ import 'package:hmg_patient_app_new/presentation/health_calculators_and_converts
import 'package:hmg_patient_app_new/presentation/health_trackers/add_health_tracker_entry_page.dart';
import 'package:hmg_patient_app_new/presentation/health_trackers/health_tracker_detail_page.dart';
import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_page.dart';
import 'package:hmg_patient_app_new/presentation/home/app_update_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_procedures_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
@ -61,6 +62,7 @@ class AppRoutes {
static const String huaweiHealthExample = '/huaweiHealthExample';
static const String covid19Test = '/covid19Test';
static const String vitalSign = '/vitalSign';
static const String appUpdate = '/appUpdate';
//appointments
static const String bookAppointmentPage = '/bookAppointmentPage';
@ -123,6 +125,9 @@ class AppRoutes {
healthConvertersPage: (context) => HealthCalculatorsPage(type: HealthCalConEnum.converter),
healthTrackersPage: (context) => HealthTrackersPage(),
vitalSign: (context) => VitalSignPage(),
appUpdate: (context) => AppUpdatePage(
appUpdateMessage: '',
),
emergencyServicesPage: (context) => EmergencyServicesPage(),
servicesPriceListPage: (context) => ServicesPriceListPage(),
addHealthTrackerEntryPage: (context) {

@ -103,7 +103,7 @@ class _AppLanguageChangeState extends State<AppLanguageChange> {
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
title.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded,
title.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, fontFamily: _value == "ar" ? 'GESSTwo' : 'Poppins').expanded,
],
).paddingOnly(left: 16, right: 16).onPress(() {
setState(() {

@ -33,7 +33,7 @@ class BottomNavigation extends StatelessWidget {
),
appState.isAuthenticated
// ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr(context: context))
? BottomNavItem(icon: AppAssets.symptomCheckerBottomIcon, fillIcon: AppAssets.symptomCheckerBottomFillIcon, label: "Symptoms")
? BottomNavItem(icon: AppAssets.symptomCheckerBottomIcon, fillIcon: AppAssets.symptomCheckerBottomFillIcon, label: LocaleKeys.symptoms.tr(context: context))
: BottomNavItem(icon: AppAssets.news, fillIcon: AppAssets.newsFill, label: LocaleKeys.news.tr()),
BottomNavItem(icon: AppAssets.servicesBottom, fillIcon: AppAssets.servicesBottomFill, label: LocaleKeys.services2.tr(context: context)),
];

@ -183,6 +183,7 @@ void showCommonBottomSheetWithoutHeight(
isScrollControlled: true,
showDragHandle: false,
isDismissible: isDismissible,
enableDrag: isDismissible,
backgroundColor: backgroundColor,
useSafeArea: useSafeArea,
builder: (BuildContext context) {

@ -2,7 +2,7 @@ name: hmg_patient_app_new
description: "New HMG Patient App"
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
version: 0.0.1+3
environment:
sdk: ">=3.6.0 <4.0.0"
@ -67,6 +67,7 @@ dependencies:
equatable: ^2.0.7
google_api_availability: ^5.0.1
firebase_analytics: ^11.5.1
firebase_crashlytics: ^4.3.8
jiffy: ^6.4.3
hijri_gregorian_calendar: ^0.1.1
sms_otp_auto_verify: ^2.2.0
@ -83,6 +84,7 @@ dependencies:
open_filex: ^4.7.0
flutter_swiper_view: ^1.1.8
flutter_callkit_incoming: ^3.0.0
in_app_update: ^4.2.5
# device_preview: ^1.3.1
location: ^8.0.1

Loading…
Cancel
Save