From b1244f0bf3fc65fe8c457d6179d3d06bc0b33f11 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 13 Oct 2021 13:55:04 +0300 Subject: [PATCH 01/60] Huawei MapTiles loading issue fix by apply signing on App and AGConnect --- android/app/agconnect-services-new.json | 74 ++++++++++++++++++++++++ android/app/build.gradle | 18 ++++-- android/app/key | Bin 0 -> 2051 bytes android/app/keystores/keystore | 0 lib/config/config.dart | 4 +- 5 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 android/app/agconnect-services-new.json create mode 100644 android/app/key create mode 100644 android/app/keystores/keystore diff --git a/android/app/agconnect-services-new.json b/android/app/agconnect-services-new.json new file mode 100644 index 00000000..fce77eec --- /dev/null +++ b/android/app/agconnect-services-new.json @@ -0,0 +1,74 @@ +{ + "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" + } + } + ] +} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index bfe7fde4..35dd8a50 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -52,12 +52,21 @@ android { } + signingConfigs { + config{ + storeFile file('key') + keyAlias 'HMG' + storePassword 'HmGsa123' + keyPassword 'HmGsa123' + } + } + buildTypes { - debug {} + debug { + signingConfig signingConfigs.config + } release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug + signingConfig signingConfigs.config } staging { // Specifies a sorted list of fallback build types that the @@ -100,4 +109,5 @@ dependencies { implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android implementation 'com.google.android.gms:play-services-basement:17.5.0' + } diff --git a/android/app/key b/android/app/key new file mode 100644 index 0000000000000000000000000000000000000000..15b9f5d1307057e4b8e4bcd4381b23424811dac6 GIT binary patch literal 2051 zcmV+e2>kc{?f&fm000620003100031188k$0003(nN@t?000F5FoFd9Fb)O^D+U1s z0V)C!0RaU71cC(UgT>MCv(e@oDfNKKat;@%p4`DkvJuL`PH*E2{RRXpj8X+Vz6u)a zevfZjqLBl;cIY2&J>kVSmOnh85TlNca*tXy=ZzdqZ*Vi#m^yl{Ll6A;Sd={hT?IVR-vm zsFm$Js?Q^dp9o!qSRcSdC^2E_AlP7`-vDF*M#8~os|f9W9B0|TdDv}@ySNta&9Yrn ztMWQJdtXeJsd1 zKq<_)z$Ik+N!g%?b$VpY+coA!nEY&wh_Ohc8}1-jTREU#|5OvLK{({;mDBQeMpig# zTehwn0;k~~hLqrb;vtW@Me}!^uWZOw$iVnMV3srhjO=L)oJUX!(qD1ses|u&Nwioz zj+o`f9ed0UZJG6Ab~*}zEV>~R%-bZlckN2=)AHQqfI9a2&r!4j#F|-{Hey;yL;eas z!}{x-W9p?rgJgllLS=%ZZCI}uwYVNVts-(A;Vri?b2$bR<6+^mo?6~bi<6gK;zdIQ!icx8FBm&qi8FROwQbzQ zw|)D%S6A->!Z!SufL%t0YI;<{3u6GuZg&{;MqWRJ+`evF^h>P(WH3BA23c)%y!|yRfZ5fr(kpW{ zCf1T3e59lbZ_(19wN;BVSk`6GK}L~z=&IqjxqpUB(3%~!t38n%yAnb^KvwxHS|)Z` zmzS*45qo}8{IjS=Wr@;;HP#Ci%UCc)>vb>CL8+e9s1xSeeKD*@>}^Cl1P4wz#3Tn} z|45J2ehH;v4w5vX*?7lVO+z8V0000100mesH842<00O@-f&#lRf&rtT0|Eg80t5r% zH@Pqk1_>&LNQUzjQ&MLzN8IfTy_}v&8I@pw%wKNScy*LA3rc7KjA4 zWfC{O=iO5mqz#*(q&OyMdnNv6mZ@&>3L=UiQdm+;^2KQfDfoF=Djh9`E|#|nE*@Xh z(G2O~7*w_rC*WzLtCZ_O*hL%9*LNl!ullZ1L4!w0-YQ_Zb?SEbCN_?}r-r_nag8Ej zPm?AO0!sn|0RRD`Aut~>9R>qc9S#H*1Qd_SMR1N)p%d$|2yTd-kw{+84ni;u1_>&L zNQU-FMCu!XEeENt zbZYF>l?W5mT{|+Z_k)_(okzb+Ou{tP5Eh&Yha7vf3Zj*o9Y2*$m~-ET@4PCHJr+g= zI;*a_R6jK`yvN45zw?CC)lzz8uUW_?;Xz5T+b8EF9*97}49<0J|DmrGoq;v=4Vw=b zO*`9K?i9?i)Dsf$QBJ(@l{NnX&kh4pp^|M%ab0gp&nG4+V65?Tip%_;*SP45Fj)Xr hRD#uFfsONE{KL;10I7=mQW|g4`W}C56fpelh$yQ4rvv~1 literal 0 HcmV?d00001 diff --git a/android/app/keystores/keystore b/android/app/keystores/keystore new file mode 100644 index 00000000..e69de29b diff --git a/lib/config/config.dart b/lib/config/config.dart index 7840b97d..d7ffabcd 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; From 3be7f7f8990abed5832c90fa59840d82ad5a39fa Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Mon, 18 Oct 2021 11:23:12 +0300 Subject: [PATCH 02/60] fixed loader issue --- lib/pages/final_products_page.dart | 9 ++++----- lib/pages/parent_categorise_page.dart | 8 ++++---- lib/pages/sub_categorise_page.dart | 9 ++++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 7e8385f0..854b66a6 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -621,19 +621,18 @@ class _FinalProductsPageState extends State { size: 18, color: Colors.blue,), onPressed: () async { - GifLoaderDialogUtils.showMyDialog(context); if(model.finalProducts[index].rxMessage == null){ + GifLoaderDialogUtils.showMyDialog(context); await addToCartFunction(1, model.finalProducts[index].id); -// GifLoaderDialogUtils.hideDialog(context); + GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, - FadePage(page: CartOrderPage()), - ); + FadePage(page: CartOrderPage())); } else{ AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); } - GifLoaderDialogUtils.hideDialog(context); +// } ), diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index 1ac20946..18133bb2 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -1175,18 +1175,18 @@ class _ParentCategorisePageState extends State { size: 18, color: Colors.blue,), onPressed: () async { - GifLoaderDialogUtils.showMyDialog(context); if(model.parentProducts[index].rxMessage == null){ + GifLoaderDialogUtils.showMyDialog(context); await addToCartFunction(1, model.parentProducts[index].id); + GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, - FadePage(page: CartOrderPage()), - ); + FadePage(page: CartOrderPage())); } else{ AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); } - GifLoaderDialogUtils.hideDialog(context); + } ), diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index 3fb1574f..6c41f550 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -1072,18 +1072,17 @@ class _SubCategorisePageState extends State { size: 18, color: Colors.blue,), onPressed: () async { - GifLoaderDialogUtils.showMyDialog(context); if(model.subProducts[index].rxMessage == null){ + GifLoaderDialogUtils.showMyDialog(context); await addToCartFunction(1, model.subProducts[index].id); -// GifLoaderDialogUtils.hideDialog(context); + GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, - FadePage(page: CartOrderPage()), - );} + FadePage(page: CartOrderPage()));} else{ AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); } - GifLoaderDialogUtils.hideDialog(context); + } ), From d0986fcaf68dcc3f3b3e616966f3d327138b96f6 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 18 Oct 2021 17:44:01 +0300 Subject: [PATCH 03/60] OpenTok SDK applied and method channels written to native --- android/app/build.gradle | 5 +- .../diplomaticquarterapp/MainActivity.kt | 11 +- .../diplomaticquarterapp/opentok/OpenTok.kt | 170 +++++++++++ .../diplomaticquarterapp/opentok/Video.kt | 63 ++++ .../utils/OpenTokPlatformBridge.kt | 50 ++++ .../utils/PlatformBridge.kt | 7 +- android/build.gradle | 7 +- ios/Flutter/.last_build_id | 2 +- ios/Podfile | 1 + ios/Podfile.lock | 26 +- ios/Runner.xcodeproj/project.pbxproj | 16 + ios/Runner/AppDelegate.swift | 6 +- ios/Runner/Helper/HMGPlatformBridge.swift | 2 +- ios/Runner/Helper/OpenTokPlatformBridge.swift | 59 ++++ ios/Runner/OpenTok/OpenTok.swift | 273 ++++++++++++++++++ 15 files changed, 682 insertions(+), 16 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt create mode 100644 ios/Runner/Helper/OpenTokPlatformBridge.swift create mode 100644 ios/Runner/OpenTok/OpenTok.swift diff --git a/android/app/build.gradle b/android/app/build.gradle index 35dd8a50..f13bce1b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -107,7 +107,10 @@ dependencies { implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android - implementation 'com.google.android.gms:play-services-basement:17.5.0' + implementation 'com.google.android.gms:play-services-basement:17.5.0' + + + implementation "com.opentok.android:opentok-android-sdk:2.19.1" } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt index 26484b5c..e754e44c 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -4,15 +4,16 @@ import android.util.Log import androidx.annotation.NonNull; import com.ejada.hmg.utils.* import io.flutter.embedding.android.FlutterFragmentActivity - import io.flutter.embedding.engine.FlutterEngine +import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterFragmentActivity() { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - // Create Flutter Platform Bridge - PlatformBridge(flutterEngine.dartExecutor.binaryMessenger, this).create() + GeneratedPluginRegistrant.registerWith(flutterEngine); + // Create Flutter Platform Bridge + PlatformBridge(flutterEngine, this).create() + OpenTokPlatformBridge(flutterEngine, this).create() val time = timeToMillis("04:00:00", "HH:mm:ss") @@ -24,7 +25,7 @@ class MainActivity: FlutterFragmentActivity() { // val d5 = Logs.GeofenceEvent.list(this) // val d6 = Logs.GeofenceEvent.raw(this) - } + } override fun onResume() { super.onResume() diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt new file mode 100644 index 00000000..5606343f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt @@ -0,0 +1,170 @@ +package com.example.basic_video_chat_flutter + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.opentok.android.* +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.StandardMessageCodec +import io.flutter.plugin.platform.PlatformView +import io.flutter.plugin.platform.PlatformViewFactory + + +enum class SdkState { + LOGGED_OUT, + LOGGED_IN, + WAIT, + ERROR +} + +class OpenTok(private var context: Context, private var flutterEngine: FlutterEngine){ + private lateinit var opentokVideoPlatformView: OpentokVideoPlatformView + + init { + opentokVideoPlatformView = OpentokVideoFactory.getViewInstance(context) + flutterEngine + .platformViewsController + .registry + // opentok-video-container is a custom platform-view-type + .registerViewFactory("opentok-video-container", OpentokVideoFactory()) + } + + private var session: Session? = null + private var publisher: Publisher? = null + private var subscriber: Subscriber? = null + + + + private val sessionListener: Session.SessionListener = object: Session.SessionListener { + override fun onConnected(session: Session) { + // Connected to session + Log.d("MainActivity", "Connected to session ${session.sessionId}") + + publisher = Publisher.Builder(context).build().apply { + setPublisherListener(publisherListener) + renderer?.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) + + view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) + opentokVideoPlatformView.publisherContainer.addView(view) + } + + notifyFlutter(SdkState.LOGGED_IN) + session.publish(publisher) + } + + override fun onDisconnected(session: Session) { + notifyFlutter(SdkState.LOGGED_OUT) + } + + override fun onStreamReceived(session: Session, stream: Stream) { + Log.d( + "MainActivity", + "onStreamReceived: New Stream Received " + stream.streamId + " in session: " + session.sessionId + ) + if (subscriber == null) { + subscriber = Subscriber.Builder(context, stream).build().apply { + renderer?.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) + setSubscriberListener(subscriberListener) + session.subscribe(this) + + opentokVideoPlatformView.subscriberContainer.addView(view) + } + } + } + + override fun onStreamDropped(session: Session, stream: Stream) { + Log.d( + "MainActivity", + "onStreamDropped: Stream Dropped: " + stream.streamId + " in session: " + session.sessionId + ) + + if (subscriber != null) { + subscriber = null + + opentokVideoPlatformView.subscriberContainer.removeAllViews() + } + } + + override fun onError(session: Session, opentokError: OpentokError) { + Log.d("MainActivity", "Session error: " + opentokError.message) + notifyFlutter(SdkState.ERROR) + } + } + + private val publisherListener: PublisherKit.PublisherListener = object : PublisherKit.PublisherListener { + override fun onStreamCreated(publisherKit: PublisherKit, stream: Stream) { + Log.d("MainActivity", "onStreamCreated: Publisher Stream Created. Own stream " + stream.streamId) + } + + override fun onStreamDestroyed(publisherKit: PublisherKit, stream: Stream) { + Log.d("MainActivity", "onStreamDestroyed: Publisher Stream Destroyed. Own stream " + stream.streamId) + } + + override fun onError(publisherKit: PublisherKit, opentokError: OpentokError) { + Log.d("MainActivity", "PublisherKit onError: " + opentokError.message) + notifyFlutter(SdkState.ERROR) + } + } + + var subscriberListener: SubscriberKit.SubscriberListener = object : SubscriberKit.SubscriberListener { + override fun onConnected(subscriberKit: SubscriberKit) { + Log.d("MainActivity", "onConnected: Subscriber connected. Stream: " + subscriberKit.stream.streamId) + } + + override fun onDisconnected(subscriberKit: SubscriberKit) { + Log.d("MainActivity", "onDisconnected: Subscriber disconnected. Stream: " + subscriberKit.stream.streamId) + notifyFlutter(SdkState.LOGGED_OUT) + } + + override fun onError(subscriberKit: SubscriberKit, opentokError: OpentokError) { + Log.d("MainActivity", "SubscriberKit onError: " + opentokError.message) + notifyFlutter(SdkState.ERROR) + } + } + + fun initSession(call: MethodCall, result: MethodChannel.Result) { + + val apiKey = requireNotNull(call.argument("apiKey")) + val sessionId = requireNotNull(call.argument("sessionId")) + val token = requireNotNull(call.argument("token")) + + notifyFlutter(SdkState.WAIT) + session = Session.Builder(context, apiKey, sessionId).build() + session?.setSessionListener(sessionListener) + session?.connect(token) + result.success("") + } + + fun swapCamera(call: MethodCall, result: MethodChannel.Result) { + publisher?.cycleCamera() + result.success("") + } + + fun toggleAudio(call: MethodCall, result: MethodChannel.Result) { + val publishAudio = requireNotNull(call.argument("publishAudio")) + publisher?.publishAudio = publishAudio + result.success("") + } + + fun toggleVideo(call: MethodCall, result: MethodChannel.Result) { + val publishVideo = requireNotNull(call.argument("publishVideo")) + publisher?.publishVideo = publishVideo + result.success("") + } + + private fun notifyFlutter(state: SdkState) { + Handler(Looper.getMainLooper()).post { + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "OpenTok-Platform-Bridge") + .invokeMethod("updateState", state.toString()) + } + } +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt new file mode 100644 index 00000000..0153908a --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt @@ -0,0 +1,63 @@ +package com.example.basic_video_chat_flutter + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.FrameLayout +import android.widget.LinearLayout +import io.flutter.plugin.common.StandardMessageCodec +import io.flutter.plugin.platform.PlatformView +import io.flutter.plugin.platform.PlatformViewFactory + +class OpentokVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { + + companion object { + private lateinit var view: OpentokVideoPlatformView + + fun getViewInstance(context: Context): OpentokVideoPlatformView { + if(!this::view.isInitialized) { + view = OpentokVideoPlatformView(context) + } + + return view + } + } + + override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + return getViewInstance(context) + } +} + +class OpentokVideoPlatformView(context: Context) : PlatformView { + private val videoContainer: OpenTokVideoContainer = OpenTokVideoContainer(context) + + val subscriberContainer get() = videoContainer.subscriberContainer + val publisherContainer get() = videoContainer.publisherContainer + + override fun getView(): View { + return videoContainer + } + + override fun dispose() {} +} + +class OpenTokVideoContainer @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, + defStyleRes: Int = 0 +) : LinearLayout(context, attrs, defStyle, defStyleRes) { + + var subscriberContainer: FrameLayout + private set + + var publisherContainer: FrameLayout + private set + + init { + val view = LayoutInflater.from(context).inflate(R.layout.view_video, this, true) + subscriberContainer = view.findViewById(R.id.subscriber_container) + publisherContainer = view.findViewById(R.id.publisher_container) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt new file mode 100644 index 00000000..29ded185 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt @@ -0,0 +1,50 @@ +package com.ejada.hmg.utils + +import android.content.Context +import android.net.wifi.WifiManager +import android.util.Log +import com.ejada.hmg.MainActivity +import com.ejada.hmg.hmgwifi.HMG_Guest +import com.ejada.hmg.hmgwifi.HMG_Internet +import com.ejada.hmg.geofence.GeoZoneModel +import com.ejada.hmg.geofence.HMG_Geofence +import com.example.basic_video_chat_flutter.OpenTok +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel + +class OpenTokPlatformBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) { + + private lateinit var channel: MethodChannel + private lateinit var openTok: OpenTok + + companion object { + private const val CHANNEL = "OpenTok-Platform-Bridge" + } + + fun create(){ + openTok = OpenTok(mainActivity, flutterEngine) + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> + when (call.method) { + "initSession" -> { + openTok.initSession(call, result) + } + "swapCamera" -> { + openTok.swapCamera(call, result) + } + "toggleAudio" -> { + openTok.toggleAudio(call, result) + } + "toggleVideo" -> { + openTok.toggleVideo(call, result) + } + else -> { + result.notImplemented() + } + } + } + } + +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt index cb8c2c3d..003b9e24 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt @@ -8,13 +8,12 @@ import com.ejada.hmg.hmgwifi.HMG_Guest import com.ejada.hmg.hmgwifi.HMG_Internet import com.ejada.hmg.geofence.GeoZoneModel import com.ejada.hmg.geofence.HMG_Geofence +import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel -class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: MainActivity) { - private var binaryMessenger = binaryMessenger - private var mainActivity = flutterMainActivity +class PlatformBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) { private lateinit var channel: MethodChannel @@ -28,7 +27,7 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main } fun create(){ - channel = MethodChannel(binaryMessenger, CHANNEL) + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) HMGUtils.setPlatformChannel(channel) channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result -> diff --git a/android/build.gradle b/android/build.gradle index 4ef0d731..ecb1ed70 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -23,7 +23,12 @@ allprojects { google() // jcenter() mavenCentral() - maven { url 'https://developer.huawei.com/repo/' } + maven { + url 'https://developer.huawei.com/repo/' + } + maven{ + url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" + } } } diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index d070415c..3aa2cd1e 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -e52eba3667a38bec777870899c15ae7d \ No newline at end of file +3f3d14a0ae775b56806906c2cb14a1f0 \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 9fbc2933..46c98373 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -42,6 +42,7 @@ target 'Runner' do # Native Pods pod 'NVActivityIndicatorView' + pod 'OpenTok' # Flutter Pod diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2ce396c4..549f5592 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -370,6 +370,10 @@ PODS: - Flutter - flutter_tts (0.0.1): - Flutter + - flutter_webrtc (0.2.2): + - Flutter + - GoogleWebRTC (= 1.1.31999) + - Libyuv (= 1703) - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) @@ -410,6 +414,7 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger + - GoogleWebRTC (1.1.31999) - "gRPC-C++ (1.28.2)": - "gRPC-C++/Implementation (= 1.28.2)" - "gRPC-C++/Interface (= 1.28.2)" @@ -438,6 +443,8 @@ PODS: - Flutter - "huawei_location (5.0.0+301)": - Flutter + - "huawei_map (5.0.3+303)": + - Flutter - image_cropper (0.0.3): - Flutter - TOCropViewController (~> 2.5.4) @@ -446,6 +453,7 @@ PODS: - just_audio (0.0.1): - Flutter - leveldb-library (1.22) + - Libyuv (1703) - local_auth (0.0.1): - Flutter - location (0.0.1): @@ -469,6 +477,7 @@ PODS: - NVActivityIndicatorView (5.1.1): - NVActivityIndicatorView/Base (= 5.1.1) - NVActivityIndicatorView/Base (5.1.1) + - OpenTok (2.20.0) - path_provider (0.0.1): - Flutter - path_provider_linux (0.0.1): @@ -562,10 +571,12 @@ DEPENDENCIES: - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - flutter_tts (from `.symlinks/plugins/flutter_tts/ios`) + - flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`) - geolocator (from `.symlinks/plugins/geolocator/ios`) - google_maps_flutter (from `.symlinks/plugins/google_maps_flutter/ios`) - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - huawei_location (from `.symlinks/plugins/huawei_location/ios`) + - huawei_map (from `.symlinks/plugins/huawei_map/ios`) - image_cropper (from `.symlinks/plugins/image_cropper/ios`) - image_picker (from `.symlinks/plugins/image_picker/ios`) - just_audio (from `.symlinks/plugins/just_audio/ios`) @@ -577,6 +588,7 @@ DEPENDENCIES: - native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`) - nfc_in_flutter (from `.symlinks/plugins/nfc_in_flutter/ios`) - NVActivityIndicatorView + - OpenTok - path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) @@ -624,12 +636,15 @@ SPEC REPOS: - GoogleDataTransport - GoogleMaps - GoogleUtilities + - GoogleWebRTC - "gRPC-C++" - gRPC-Core - leveldb-library + - Libyuv - MTBBarcodeScanner - nanopb - NVActivityIndicatorView + - OpenTok - PromisesObjC - Protobuf - Reachability @@ -688,6 +703,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" flutter_tts: :path: ".symlinks/plugins/flutter_tts/ios" + flutter_webrtc: + :path: ".symlinks/plugins/flutter_webrtc/ios" geolocator: :path: ".symlinks/plugins/geolocator/ios" google_maps_flutter: @@ -696,6 +713,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/hexcolor/ios" huawei_location: :path: ".symlinks/plugins/huawei_location/ios" + huawei_map: + :path: ".symlinks/plugins/huawei_map/ios" image_cropper: :path: ".symlinks/plugins/image_cropper/ios" image_picker: @@ -808,6 +827,7 @@ SPEC CHECKSUMS: flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d + flutter_webrtc: 39898454258b54ba51996850d5da8d5d53bf1524 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a geolocator: f5e3de65e241caba7ce3e8a618803387bda73384 google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 @@ -815,14 +835,17 @@ SPEC CHECKSUMS: GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + GoogleWebRTC: b39a78c4f5cc6b0323415b9233db03a2faa7b0f0 "gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2 gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5 hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 huawei_location: a1c3d2a029138b3d0b9a72ce910ffae3ff23c1aa + huawei_map: 34fbad9c274ea78a4151487c9ebe27f1887777e7 image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4 image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7 + Libyuv: 5f79ced0ee66e60a612ca97de1e6ccacd187a437 local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd location: 3a2eed4dd2fab25e7b7baf2a9efefe82b512d740 manage_calendar_events: 0338d505ea26cdfd20cd883279bc28afa11eca34 @@ -833,6 +856,7 @@ SPEC CHECKSUMS: native_device_orientation: e24d00be281de72996640885d80e706142707660 nfc_in_flutter: c656fbfb1ec5b9d021da87b0c87629d62fd5264d NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667 + OpenTok: 414c2c1dc6486f1897015e4d1703558d5eed48c3 path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 @@ -869,6 +893,6 @@ SPEC CHECKSUMS: webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 wifi: d7d77c94109e36c4175d845f0a5964eadba71060 -PODFILE CHECKSUM: 900f7dc480de5b961c031ed418407e0e40ed455c +PODFILE CHECKSUM: df22e8ed6009dd48559053927dc365d6dad6c11f COCOAPODS: 1.10.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e4453fa6..9505487e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; + 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */; }; @@ -50,6 +52,8 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; }; + 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; }; 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; @@ -99,6 +103,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 306FE6C9271D8B54002D6EFC /* OpenTok */ = { + isa = PBXGroup; + children = ( + 306FE6CA271D8B73002D6EFC /* OpenTok.swift */, + ); + path = OpenTok; + sourceTree = ""; + }; 555EAAA626EFB641859EF0BE /* Frameworks */ = { isa = PBXGroup; children = ( @@ -153,6 +165,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 306FE6C9271D8B54002D6EFC /* OpenTok */, E91B539E256AAC1400E96549 /* GuestPOC_Certificate.cer */, E91B539D256AAC1400E96549 /* GuestPOC_Certificate.p12 */, E91B5390256AAA6500E96549 /* Controllers */, @@ -182,6 +195,7 @@ E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */, E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, ); path = Helper; @@ -375,6 +389,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */, E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, @@ -382,6 +397,7 @@ E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, + 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index c4a74c80..35a3c022 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -14,7 +14,7 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil GMSServices.provideAPIKey("AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw") GeneratedPluginRegistrant.register(with: self) - initializePlatformChannel() + initializePlatformChannels() if let _ = launchOptions?[.location] { HMG_Geofence.initGeofencing() @@ -25,14 +25,16 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil } - func initializePlatformChannel(){ + func initializePlatformChannels(){ if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground flutterViewController = mainViewController HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background flutterViewController = mainViewController HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) } } diff --git a/ios/Runner/Helper/HMGPlatformBridge.swift b/ios/Runner/Helper/HMGPlatformBridge.swift index f94f9b34..fd9fb401 100644 --- a/ios/Runner/Helper/HMGPlatformBridge.swift +++ b/ios/Runner/Helper/HMGPlatformBridge.swift @@ -10,7 +10,7 @@ import NetworkExtension import SystemConfiguration.CaptiveNetwork var flutterMethodChannel:FlutterMethodChannel? = nil -var mainViewController:MainFlutterVC! +fileprivate var mainViewController:MainFlutterVC! class HMGPlatformBridge{ private let channelName = "HMG-Platform-Bridge" diff --git a/ios/Runner/Helper/OpenTokPlatformBridge.swift b/ios/Runner/Helper/OpenTokPlatformBridge.swift new file mode 100644 index 00000000..38e826e1 --- /dev/null +++ b/ios/Runner/Helper/OpenTokPlatformBridge.swift @@ -0,0 +1,59 @@ +// +// HMGPlatformBridge.swift +// Runner +// +// Created by ZiKambrani on 14/12/2020. +// + +import UIKit +import NetworkExtension +import SystemConfiguration.CaptiveNetwork +import OpenTok + + +fileprivate var openTok:OpenTok? + +class OpenTokPlatformBridge : NSObject{ + private var methodChannel:FlutterMethodChannel? = nil + private var mainViewController:MainFlutterVC! + private static var shared_:OpenTokPlatformBridge? + + class func initialize(flutterViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){ + shared_ = OpenTokPlatformBridge() + shared_?.mainViewController = flutterViewController + + shared_?.openChannel() + openTok = OpenTok(mainViewController: flutterViewController, registrar: registrar) + } + + func shared() -> OpenTokPlatformBridge{ + assert((OpenTokPlatformBridge.shared_ != nil), "OpenTokPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.") + return OpenTokPlatformBridge.shared_! + } + + private func openChannel(){ + methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger) + methodChannel?.setMethodCallHandler { (call, result) in + print("Called function \(call.method)") + + switch(call.method) { + case "initSession": + openTok?.initSession(call: call, result: result) + + case "swapCamera": + openTok?.swapCamera(call: call, result: result) + + case "toggleAudio": + openTok?.toggleAudio(call: call, result: result) + + case "toggleVideo": + openTok?.toggleVideo(call: call, result: result) + + default: + result(FlutterMethodNotImplemented) + } + + print("") + } + } +} diff --git a/ios/Runner/OpenTok/OpenTok.swift b/ios/Runner/OpenTok/OpenTok.swift new file mode 100644 index 00000000..3cb7fdbe --- /dev/null +++ b/ios/Runner/OpenTok/OpenTok.swift @@ -0,0 +1,273 @@ +// +// OpenTok.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 18/10/2021. +// + +import Foundation +import OpenTok + +enum SdkState: String { + case loggedOut = "LOGGED_OUT" + case loggedIn = "LOGGED_IN" + case wait = "WAIT" + case error = "ERROR" +} + +class OpenTok : NSObject{ + private var mainViewController:MainFlutterVC! + private var registrar:FlutterPluginRegistrar? + init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){ + self.mainViewController = mainViewController + self.registrar = registrar + + let factory = OpentokVideoFactory(messenger: registrar!.messenger()) + registrar?.register(factory, withId: "opentok-video-container") + } + + var otSession: OTSession? + var vonageChannel: FlutterMethodChannel? + + var subscriber: OTSubscriber? + lazy var publisher: OTPublisher = { + let settings = OTPublisherSettings() + settings.name = UIDevice.current.name + return OTPublisher(delegate: self, settings: settings)! + }() + + func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){ + if let arguments = call.arguments as? [String: String], + let apiKey = arguments["apiKey"], + let sessionId = arguments["sessionId"], + let token = arguments["token"]{ + + var error: OTError? + defer { + // todo + } + + notifyFlutter(state: SdkState.wait) + otSession = OTSession(apiKey: apiKey, sessionId: sessionId, delegate: self)! + otSession?.connect(withToken: token, error: &error) + + result("") + }else{ + + } + + } + + + func swapCamera(call:FlutterMethodCall, result: @escaping FlutterResult) { + if publisher.cameraPosition == .front { + publisher.cameraPosition = .back + } else { + publisher.cameraPosition = .front + } + result("") + } + + func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) { + if let arguments = call.arguments as? [String: Bool], + let publishAudio = arguments["publishAudio"] { + publisher.publishAudio = !publisher.publishAudio + } + result("") + } + + func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) { + if let arguments = call.arguments as? [String: Bool], + let publishVideo = arguments["publishVideo"] { + publisher.publishVideo = !publisher.publishVideo + } + result("") + } + + + func notifyFlutter(state: SdkState) { + vonageChannel?.invokeMethod("updateState", arguments: state.rawValue) + } + +} + +extension OpenTok: OTSessionDelegate { + func sessionDidConnect(_ sessionDelegate: OTSession) { + print("The client connected to the session.") + notifyFlutter(state: SdkState.loggedIn) + + var error: OTError? + defer { + // todo + } + + self.otSession?.publish(self.publisher, error: &error) + + if let pubView = self.publisher.view { + pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300) + + if OpentokVideoFactory.view == nil { + OpentokVideoFactory.viewToAddPub = pubView + } else { + OpentokVideoFactory.view?.addPublisherView(pubView) + } + } + } + + func sessionDidDisconnect(_ session: OTSession) { + print("The client disconnected from the session.") + notifyFlutter(state: SdkState.loggedOut) + } + + func session(_ session: OTSession, didFailWithError error: OTError) { + print("The client failed to connect to the session: \(error).") + } + + func session(_ session: OTSession, streamCreated stream: OTStream) { + print("A stream was created in the session.") + var error: OTError? + defer { + // todo + } + subscriber = OTSubscriber(stream: stream, delegate: self) + + session.subscribe(subscriber!, error: &error) + } + + func session(_ session: OTSession, streamDestroyed stream: OTStream) { + print("A stream was destroyed in the session.") + } +} + +extension OpenTok: OTPublisherDelegate { + func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) { + } + + func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) { + } + + func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { + print("Publisher failed: \(error.localizedDescription)") + } +} + +extension OpenTok: OTSubscriberDelegate { + func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) { + print("Subscriber connected") + + if let subView = self.subscriber?.view { + subView.frame = CGRect(x: 0, y: 0, width: 200, height: 300) + + if OpentokVideoFactory.view == nil { + OpentokVideoFactory.viewToAddSub = subView + } else { + OpentokVideoFactory.view?.addSubscriberView(subView) + } + } + } + + func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { + print("Subscriber failed: \(error.localizedDescription)") + } + +} + +class OpentokVideoFactory: NSObject, FlutterPlatformViewFactory { + static var view: OpentokVideoPlatformView? + + static var viewToAddSub: UIView? + static var viewToAddPub: UIView? + + static func getViewInstance( + frame: CGRect, + viewId: Int64, + args: Any?, + messenger: FlutterBinaryMessenger? + ) -> OpentokVideoPlatformView{ + if(view == nil) { + view = OpentokVideoPlatformView() + if viewToAddSub != nil { + view?.addSubscriberView(viewToAddSub!) + } + if viewToAddPub != nil { + view?.addPublisherView(viewToAddPub!) + } + } + + return view! + } + + private var messenger: FlutterBinaryMessenger + + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return OpentokVideoFactory.getViewInstance( + frame: frame, + viewId: viewId, + args: args, + messenger: messenger) + } +} + +class OpentokVideoPlatformView: NSObject, FlutterPlatformView { + private let videoContainer: OpenTokVideoContainer + + override init() { + videoContainer = OpenTokVideoContainer() + super.init() + } + + public func addSubscriberView(_ view: UIView) { + videoContainer.addSubscriberView(view) + } + + public func addPublisherView(_ view: UIView) { + videoContainer.addPublisherView(view) + } + + func view() -> UIView { + return videoContainer + } +} + +final class OpenTokVideoContainer: UIView { + private let subscriberContainer = UIView() + private let publisherContainer = UIView() + + init() { + super.init(frame: .zero) + addSubview(subscriberContainer) + addSubview(publisherContainer) + } + + + public func addSubscriberView(_ view: UIView) { + subscriberContainer.addSubview(view) + } + + public func addPublisherView(_ view: UIView) { + publisherContainer.addSubview(view) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + let width = frame.width + let height = frame.height + + let videoWidth = width / 2 + subscriberContainer.frame = CGRect(x: 0, y: 0, width: videoWidth, height: height) + publisherContainer.frame = CGRect(x: videoWidth, y: 0, width: videoWidth, height: height) + } +} From 680dcfc255de48abc64d1d492824729c2639946c Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 20 Oct 2021 17:19:10 +0300 Subject: [PATCH 04/60] In App Review --- lib/widgets/drawer/app_drawer_widget.dart | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 6209f52d..a66d5850 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -34,6 +34,7 @@ import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:in_app_review/in_app_review.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -47,6 +48,7 @@ class AppDrawer extends StatefulWidget { } class _AppDrawerState extends State { + final InAppReview _inAppReview = InAppReview.instance; @override void initState() { @@ -377,11 +379,12 @@ class _AppDrawerState extends State { InkWell( child: DrawerItem(TranslationBase.of(context).rateApp, Icons.star, bottomLine: false, letterSpacing: -0.84, fontSize: 14, projectProvider: projectProvider), onTap: () { - if (Platform.isIOS) { - launch("https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); - } else { - launch("https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); - } + openAppReviewDialog(); + // if (Platform.isIOS) { + // launch("https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); + // } else { + // launch("https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); + // } }, ), InkWell( @@ -607,6 +610,12 @@ class _AppDrawerState extends State { }); } + openAppReviewDialog() async { + if (await _inAppReview.isAvailable()) { + _inAppReview.requestReview(); + } + } + void setUserValues(value) async { if (value != null) sharedPref.setObject(IMEI_USER_DATA, value); } From 5b1f0c163e41d3f6e973b7dcd8bf8a6ed34f0cbf Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 20 Oct 2021 17:19:25 +0300 Subject: [PATCH 05/60] In App Review --- pubspec.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pubspec.yaml b/pubspec.yaml index 15c10362..49700d97 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -189,6 +189,8 @@ dependencies: in_app_update: ^1.1.15 + in_app_review: ^1.0.4 + badges: ^1.1.4 # open_settings: ^2.0.1 # Dep by Zohaib From 3db40945854e51496e315d8a0ebb1c5bd5792892 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 21 Oct 2021 16:03:58 +0300 Subject: [PATCH 06/60] Ereferral fixed, HHC moved to new APIs, Notification new design implemented --- lib/config/config.dart | 1 + lib/config/localized_values.dart | 42 ++++--- .../e_referral_service.dart | 4 + .../home_health_care_service.dart | 10 ++ .../home_health_care_view_model.dart | 3 +- .../e_referral_view_model.dart | 2 +- .../new_e_referral_step_one_page.dart | 11 +- .../new_e_referral_step_three_page.dart | 35 +++--- .../new_e_referral_step_two_page.dart | 2 +- .../E-Referral/referral_details.dart | 50 ++------- .../new_home_health_care_page.dart | 16 ++- .../orders_log_details_page.dart | 2 +- .../all_habib_medical_service_page2.dart | 36 +++--- .../health-weather-indicator.dart | 12 +- .../notifications/notifications_page.dart | 106 ++++-------------- .../fragments/home_page_fragment2.dart | 10 +- lib/pages/landing/home_page_2.dart | 2 +- lib/pages/login/login.dart | 2 +- lib/uitl/translations_delegate_base.dart | 46 +++++++- lib/widgets/bottom_options/BottomSheet.dart | 4 +- 20 files changed, 190 insertions(+), 206 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 75a904ea..7270f91e 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -442,6 +442,7 @@ const ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = 'Services/PatientVarification.svc/ const HHC_GET_ALL_SERVICES_RC = "rc/api/HHC/getallhhc"; const ADD_HHC_ORDER_RC = "rc/api/HHC/add"; const GET_ALL_HHC_ORDERS_RC = 'rc/api/hhc/list'; +const UPDATE_HHC_ORDER_RC = 'rc/api/hhc/update'; // CMC RC SERVICES const GET_ALL_CMC_SERVICES_RC = 'rc/api/cmc/getallcmc'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index bb910f6c..b4c0df07 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -633,7 +633,7 @@ const Map localizedValues = { "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي) ..." }, "email": {"en": "Email", "ar": "البريد الالكتروني"}, - "Book": {"en": "Book", "ar": "احجز"}, + "Book": {"en": "Book", "ar": "حجز"}, "AppointmentLabel": {"en": "Appointment", "ar": "موعد"}, "BloodType": {"en": "Blood Type", "ar": "فصيلة الدم"}, "marital-status": {"en": "Marital status", "ar": "الحالة الإجتماعية"}, @@ -1092,7 +1092,7 @@ const Map localizedValues = { "updated-email": {"en": "Updated email successfully", "ar": "تم تحديث البريد الالكتروني"}, "view-list-children": {"en": "View List of Children", "ar": "عرض قائمة الأطفال"}, "covidTest": {"en": "COVID-19 TEST", "ar": "فحص كورونا"}, - "driveThru": {"en": "Drive-Thru", "ar": "من السيارة"}, + "driveThru": {"en": "Drive-Thru", "ar": "من داخل السيارة"}, "trackDeliveryDriver": {"en": "Track Delivery Driver", "ar": "تتبع السائق"}, "NearestErDesc": { "en": "\nThis service Displays nearest branch\n among all the branches of All Habib \n medical Group based on your current Location", @@ -1542,24 +1542,40 @@ const Map localizedValues = { "My_File_Details": {"en": "My File Details", "ar": "تفاصيل ملفي"}, "Ecommerce": {"en": "Ecommerce", "ar": "التجارة الإلكترونية"}, "Family_Files": {"en": "Family Files", "ar": "ملفات العائلة"}, - "My_Child": {"en": "My Child", "ar": "طفلي"}, - "Vaccines": {"en": "Vaccines", "ar": "اللقاحات"}, - "Todo": {"en": "Todo", "ar": "لكى يفعل"}, - "List": {"en": "List", "ar": "قائمة"}, - "Blood": {"en": "Blood", "ar": "دم"}, - "Donation": {"en": "Donation", "ar": "هبة"}, + "My_Child": {"en": "My Child", "ar": "تطعيمات"}, + "Vaccines": {"en": "Vaccines", "ar": "الأطفال"}, + "Todo": {"en": "Todo", "ar": "قائمة"}, + "List": {"en": "List", "ar": "المهام"}, + "Blood": {"en": "Blood", "ar": "التبرع"}, + "Donation": {"en": "Donation", "ar": "بالدم"}, "Health": {"en": "Health", "ar": "الصحة"}, "Calculator": {"en": "Calculator", "ar": "آلة حاسبة"}, "Converter": {"en": "Converter", "ar": "محول"}, "Smart": {"en": "Smart", "ar": "ذكي"}, "Watches": {"en": "Watches", "ar": "ساعات"}, - "Parking": {"en": "Parking", "ar": "موقف سيارات"}, + "parkingTitle2": {"en": "Car parking", "ar": "خدمة"}, + "ParkingSubtitle": {"en": "service", "ar": "مواقف السيارات"}, "Details": {"en": "Details", "ar": "تفاصيل"}, - "Virtual": {"en": "Virtual", "ar": "افتراضية"}, - "News": {"en": "News", "ar": "أخبار"}, - "Latest": {"en": "Latest", "ar": "أحدث"}, - "Tour": {"en": "Tour", "ar": "رحلة"}, + "News": {"en": "News", "ar": "أحدث"}, + "Latest": {"en": "Latest", "ar": "ألاخبار"}, + "Virtual": {"en": "Virtual", "ar": "جولة"}, + "Tour": {"en": "Tour", "ar": "افتراضية"}, "mostViewed": {"en": "Most Viewed", "ar": "الأكثر مشاهدة"}, "newProducts": {"en": "New Products", "ar": "منتجات جديدة"}, "paymentSelected": {"en": "Selected", "ar": "المحدد"}, + "moreNotifications": {"en": "More notifications", "ar": "الإشعارات المزيد"}, + "familyTitle": {"en": "My Family", "ar": "ملفات"}, + "familySubtitle": {"en": "Files", "ar": "العائلة"}, + "liveCareTitle": {"en": "LiveCare", "ar": "خدمة"}, + "liveCareSubtitle": {"en": "Service", "ar": "لايف كير"}, + "pharmacyTitle": {"en": "Al Habib", "ar": "الصيدليات"}, + "pharmacySubtitle": {"en": "Pharmacy", "ar": "الحبيب"}, + "healthCalculatorTitle": {"en": "Health", "ar": "الحاسبات"}, + "healthCalculatorSubtitle": {"en": "Calculators", "ar": "الصحية"}, + "waterTitle": {"en": "Water", "ar": "استهلاك"}, + "waterSubtitle": {"en": "Consumption", "ar": "الماء"}, + "medicalFileTitle2": {"en": "My Medical File", "ar": "تفاصيل"}, + "medicalFileSubtitle": {"en": "Details", "ar": "ملفي الطبي"}, + "healthConvertersTitle": {"en": "Health", "ar": "تحويل"}, + "healthConvertersSubtitle": {"en": "Converters", "ar": "القياسات"}, }; diff --git a/lib/core/service/AlHabibMedicalService/e_referral_service.dart b/lib/core/service/AlHabibMedicalService/e_referral_service.dart index 7fcc5f19..f3791f4b 100644 --- a/lib/core/service/AlHabibMedicalService/e_referral_service.dart +++ b/lib/core/service/AlHabibMedicalService/e_referral_service.dart @@ -22,9 +22,12 @@ class EReferralService extends BaseService { List get allReferral => _allReferral; String _activationCode; String _logInTokenID; + String _referralNumber; String get activationCode => _activationCode; + String get referralNumber => _referralNumber; + bool _isActivationCodeValid = false; bool get isActivationCodeValid => _isActivationCodeValid; @@ -106,6 +109,7 @@ class EReferralService extends BaseService { CREATE_E_REFERRAL /*'Services/Patients.svc/REST/CreateEReferral'*/, onSuccess: (dynamic response, int statusCode) { // TODO Waiting for fix service + _referralNumber = response['ReferralNumber'].toString(); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart index 00d44f6a..cd90dae5 100644 --- a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart +++ b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart @@ -104,6 +104,16 @@ class HomeHealthCareService extends BaseService { }, body: updatePresOrderRequestModel.toJson()); } + Future updateHHCPresOrderRC(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { + hasError = false; + await baseAppClient.post(UPDATE_HHC_ORDER_RC, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: updatePresOrderRequestModel.toJson()); + } + Future insertPresPresOrder({PatientERInsertPresOrderRequestModel order}) async { hasError = false; await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { diff --git a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart index d27827e4..09b2a73d 100644 --- a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart @@ -71,7 +71,8 @@ class HomeHealthCareViewModel extends BaseViewModel { Future updateHHCPresOrder(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { setState(ViewState.Busy); - await _homeHealthCareService.updateHHCPresOrder(updatePresOrderRequestModel); + // await _homeHealthCareService.updateHHCPresOrder(updatePresOrderRequestModel); + await _homeHealthCareService.updateHHCPresOrderRC(updatePresOrderRequestModel); if (_homeHealthCareService.hasError) { error = _homeHealthCareService.error; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/all_habib_medical_services/e_referral_view_model.dart b/lib/core/viewModels/all_habib_medical_services/e_referral_view_model.dart index b1a6441e..ee803b5e 100644 --- a/lib/core/viewModels/all_habib_medical_services/e_referral_view_model.dart +++ b/lib/core/viewModels/all_habib_medical_services/e_referral_view_model.dart @@ -21,7 +21,7 @@ class EReferralViewModel extends BaseViewModel { List get allCities => _eReferralService.allCities; List get allReferral => _eReferralService.allReferral; - + String get referralNumber => _eReferralService.referralNumber; void getRelationTypes() async { setState(ViewState.Busy); diff --git a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart index 16f599d7..25efb016 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart @@ -36,6 +36,7 @@ class NewEReferralStepOnePage extends StatefulWidget { class _NewEReferralStepOnePageState extends State { TextEditingController _nameTextController = TextEditingController(); + TextEditingController _requesterRelationTextController = TextEditingController(); GetAllRelationshipTypeResponseModel _selectedRelation; String email; @@ -166,6 +167,11 @@ class _NewEReferralStepOnePageState extends State { ), ), ), + SizedBox( + height: 12, + ), + if (_selectedRelation != null && _selectedRelation.iD == 5) + inputWidget(TranslationBase.of(context).requesterRelationship, "", _requesterRelationTextController, isInputTypeNum: false), ], ), ), @@ -180,7 +186,7 @@ class _NewEReferralStepOnePageState extends State { width: double.infinity, child: DefaultButton( TranslationBase.of(context).next, - (_nameTextController.text.isEmpty || _selectedRelation == null || mobileNo.isEmpty) + (_nameTextController.text.isEmpty || _selectedRelation == null || mobileNo.isEmpty || (_selectedRelation.iD == 5 && _requesterRelationTextController.text.isEmpty)) ? null : () async { Future.delayed(new Duration(milliseconds: 300)).then((value) async { @@ -222,7 +228,8 @@ class _NewEReferralStepOnePageState extends State { Navigator.of(context).pop(); widget.changePageViewIndex(1); widget.createEReferralRequestModel.requesterName = _nameTextController.text; - widget.createEReferralRequestModel.requesterContactNo = _selectedCountry['code'].toString().substring(1) + mobileNo; + widget.createEReferralRequestModel.requesterContactNo = _selectedCountry['code'].toString() + mobileNo; + widget.createEReferralRequestModel.otherRelationship = _requesterRelationTextController.text; widget.createEReferralRequestModel.requesterRelationship = _selectedRelation.iD; } }); diff --git a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_three_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_three_page.dart index 164d7b50..439a9ec7 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_three_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_three_page.dart @@ -7,11 +7,11 @@ import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; @@ -22,7 +22,6 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import '../dialogs/select_city_dialog.dart'; @@ -111,11 +110,10 @@ class _NewEReferralStepThreePageState extends State { fontWeight: FontWeight.w600, ), ), - ...List.generate( medicalReportImages.length, (index) => Container( - padding: EdgeInsets.only(top: 6,bottom: 6), + padding: EdgeInsets.only(top: 6, bottom: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -154,7 +152,7 @@ class _NewEReferralStepThreePageState extends State { ); }, child: Padding( - padding: EdgeInsets.only(top: 12,bottom: 12), + padding: EdgeInsets.only(top: 12, bottom: 12), child: Text( TranslationBase.of(context).selectAttachment, style: TextStyle( @@ -257,10 +255,8 @@ class _NewEReferralStepThreePageState extends State { Padding( padding: const EdgeInsets.all(5.0), child: Text( - TranslationBase.of(context).insuredPatientReferral, style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600 - ), + TranslationBase.of(context).insuredPatientReferral, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), ), ), ], @@ -297,11 +293,10 @@ class _NewEReferralStepThreePageState extends State { fontWeight: FontWeight.w600, ), ), - ...List.generate( insuredPatientImages.length, (index) => Container( - padding: EdgeInsets.only(top: 6,bottom: 6), + padding: EdgeInsets.only(top: 6, bottom: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -339,7 +334,7 @@ class _NewEReferralStepThreePageState extends State { }); }, child: Padding( - padding: const EdgeInsets.only(top: 12,bottom: 12), + padding: const EdgeInsets.only(top: 12, bottom: 12), child: Text( TranslationBase.of(context).selectAttachment, style: TextStyle( @@ -378,16 +373,23 @@ class _NewEReferralStepThreePageState extends State { this.widget.createEReferralRequestModel.insuranceCardAttachment = insuredPatientImages.length != 0 ? insuredPatientImages[0] : null; this.widget.createEReferralRequestModel.isInsuredPatient = isPatientInsured; // ToDo make the preferred Branch info dynamic - this.widget.createEReferralRequestModel.preferredBranchCode = num.tryParse(projectDropdownValue.split(",")[0]); - this.widget.createEReferralRequestModel.preferredBranchName = projectDropdownValue.split(",")[1]; - this.widget.createEReferralRequestModel.otherRelationship = ""; + this.widget.createEReferralRequestModel.preferredBranchCode = projectDropdownValue != null && projectDropdownValue.isNotEmpty ? num.tryParse(projectDropdownValue.split(",")[0]) : 0; + this.widget.createEReferralRequestModel.preferredBranchName = projectDropdownValue != null && projectDropdownValue.isNotEmpty ? projectDropdownValue.split(",")[1] : ""; + // this.widget.createEReferralRequestModel.otherRelationship = ""; await model.createEReferral(this.widget.createEReferralRequestModel); if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Utils.showErrorToast(model.error); } else { GifLoaderDialogUtils.hideDialog(context); - AppToast.showSuccessToast(message: TranslationBase.of(context).ereferralSaveSuccess); + // AppToast.showSuccessToast(message: TranslationBase.of(context).ereferralSaveSuccess); + showCMCConfirmDialog( + context, + model.referralNumber, + onClick: () { + Navigator.pop(context); + }, + ); } }); }, @@ -469,7 +471,6 @@ class _NewEReferralStepThreePageState extends State { ); } - String getRelationName() { if (_selectedCity != null) return _selectedCity.description; diff --git a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart index 9135eda9..57341838 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart @@ -180,7 +180,7 @@ class _NewEReferralStepTowPageState extends State { this.widget.changePageViewIndex(2); this.widget.createEReferralRequestModel.identificationNo = int.parse(_patientIdentificationTextController.text); this.widget.createEReferralRequestModel.fullName = _patientNameTextController.text; - this.widget.createEReferralRequestModel.patientMobileNumber = _selectedCountry['code'].toString().substring(1) + mobileNo; + this.widget.createEReferralRequestModel.patientMobileNumber = _selectedCountry['code'].toString() + mobileNo; this.widget.createEReferralRequestModel.cityCode = _selectedCity.iD.toString(); this.widget.createEReferralRequestModel.cityName = _selectedCity.description; }, diff --git a/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart b/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart index fe920748..1baab531 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart @@ -31,8 +31,7 @@ class _ReferralDetailsState extends State { width: double.infinity, child: Container( decoration: cardRadius(12), - margin: - EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), child: Padding( padding: const EdgeInsets.all(15.0), child: Column( @@ -40,13 +39,7 @@ class _ReferralDetailsState extends State { children: [ Container( margin: EdgeInsets.only(bottom: 10.0), - child: Text( - TranslationBase.of(context).ereferral, - style: TextStyle( - letterSpacing: -0.64, - color: Colors.black, - fontSize: 18.0, - fontWeight: FontWeight.bold)), + child: Text(TranslationBase.of(context).ereferral, style: TextStyle(letterSpacing: -0.64, color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.bold)), ), Container( width: double.infinity, @@ -54,15 +47,10 @@ class _ReferralDetailsState extends State { child: Row( children: [ Expanded( - child: _getNormalText( - TranslationBase.of(context).referralStatus), + child: _getNormalText(TranslationBase.of(context).referralStatus), ), Expanded( - child: _getNormalText( - projectViewModel.isArabic - ? widget.referral.statusAr - : widget.referral.status, - isBold: true), + child: _getNormalText(projectViewModel.isArabic ? widget.referral.statusAr : widget.referral.status, isBold: true), ) ], ), @@ -74,13 +62,10 @@ class _ReferralDetailsState extends State { child: Row( children: [ Expanded( - child: _getNormalText( - TranslationBase.of(context).patientName), + child: _getNormalText(TranslationBase.of(context).patientName), ), Expanded( - child: _getNormalText( - widget.referral.patientName, - isBold: true), + child: _getNormalText(widget.referral.patientName, isBold: true), ) ], ), @@ -92,13 +77,10 @@ class _ReferralDetailsState extends State { child: Row( children: [ Expanded( - child: _getNormalText( - TranslationBase.of(context).referralNumber), + child: _getNormalText(TranslationBase.of(context).referralNumber), ), Expanded( - child: _getNormalText( - widget.referral.referralNumber.toString(), - isBold: true), + child: _getNormalText(widget.referral.referralNumber.toString(), isBold: true), ) ], ), @@ -110,15 +92,10 @@ class _ReferralDetailsState extends State { child: Row( children: [ Expanded( - child: _getNormalText( - TranslationBase.of(context).referralDate), + child: _getNormalText(TranslationBase.of(context).referralDate), ), Expanded( - child: _getNormalText( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDateNoTimeZone( - widget.referral.referralDate)), - isBold: true), + child: _getNormalText(DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDateNoTimeZone(widget.referral.referralDate)), isBold: true), ) ], ), @@ -130,13 +107,10 @@ class _ReferralDetailsState extends State { child: Row( children: [ Expanded( - child: _getNormalText( - TranslationBase.of(context).hospital), + child: _getNormalText(TranslationBase.of(context).hospital), ), Expanded( - child: _getNormalText( - widget.referral.preferredBranchName, - isBold: true), + child: _getNormalText(widget.referral.preferredBranchName ?? "", isBold: true), ) ], ), diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart index c4e82766..b0e98ce4 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart @@ -1,17 +1,15 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; @@ -66,14 +64,14 @@ class _NewHomeHealthCarePageState extends State with Tick @override Widget build(BuildContext context) { - void showConfirmMessage(HomeHealthCareViewModel model, GetOrderDetailByOrderIDResponseModel order) { + void showConfirmMessage(HomeHealthCareViewModel model, GetCMCAllOrdersResponseModel order) { showDialog( context: context, - child: ConfirmCancelOrderDialog( - model: model, + child: ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, onTap: () async { model.setState(ViewState.Busy); - UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.presOrderID, rejectionReason: "", presOrderStatus: 4, editedBy: 3); + UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3); await model.updateHHCPresOrder(updatePresOrderRequestModel); if (model.state == ViewState.ErrorLocal) { @@ -195,7 +193,7 @@ class _NewHomeHealthCarePageState extends State with Tick if (widget.model.pendingOrder.statusId == 1 || widget.model.pendingOrder.statusId == 2) InkWell( onTap: () { - showConfirmMessage(widget.model, widget.model.hhcAllOrderDetail[0]); + showConfirmMessage(widget.model, widget.model.pendingOrder); }, child: Container( padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart index 919c566a..22ffd68f 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart @@ -90,7 +90,7 @@ class OrdersLogDetailsPage extends StatelessWidget { } else if (status == 3) { //completed _color = Color(0xff359846); - } else if (status == 4) { + } else if (status == 4 || status == 6 || status == 7) { //cancel // Rejected _color = Color(0xffD02127); } diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart index 6aff12d7..fc3eebb5 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart @@ -48,29 +48,29 @@ class _AllHabibMedicalSevicePage2State extends State initialiseHmgServices(bool isLogin) { hmgServices.clear(); - hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); + hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCareTitle, TranslationBase.of(context).liveCareSubtitle, "assets/images/new/Live_Care.svg", isLogin)); hmgServices.add(new HmgServices(1, TranslationBase.of(context).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/covid_test_drive_thru.svg", isLogin)); hmgServices.add(new HmgServices(2, TranslationBase.of(context).onlinePayment, TranslationBase.of(context).onlinePaymentSubtitle, "assets/images/new/paymentMethods.png", isLogin)); hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); hmgServices.add(new HmgServices(4, TranslationBase.of(context).cmcTitle, TranslationBase.of(context).cmcSubtitle, "assets/images/new/comprehensive_checkup.svg", isLogin)); hmgServices.add(new HmgServices(5, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); hmgServices.add(new HmgServices(6, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); - hmgServices.add(new HmgServices(7, "H\u2082O", TranslationBase.of(context).dailyWater, "assets/images/new/h2o.svg", isLogin)); + hmgServices.add(new HmgServices(7, TranslationBase.of(context).waterTitle, TranslationBase.of(context).waterSubtitle, "assets/images/new/h2o.svg", isLogin)); hmgServices.add(new HmgServices(8, TranslationBase.of(context).findUs, TranslationBase.of(context).reachUs, "assets/images/new/reach_us.svg", isLogin)); - hmgServices.add(new HmgServices(9, TranslationBase.of(context).medicalFile, TranslationBase.of(context).My_File_Details, "assets/images/new/medical file.svg", isLogin)); - hmgServices.add(new HmgServices(10, TranslationBase.of(context).book, TranslationBase.of(context).appointment, "assets/images/new/book appointment.svg", isLogin)); - hmgServices.add(new HmgServices(11, TranslationBase.of(context).online, TranslationBase.of(context).pharmacy, "assets/images/new/Pharmacy.svg", isLogin)); + hmgServices.add(new HmgServices(9, TranslationBase.of(context).medicalFileTitle2, TranslationBase.of(context).medicalFileSubtitle, "assets/images/new/medical file.svg", isLogin)); + hmgServices.add(new HmgServices(10, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); + hmgServices.add(new HmgServices(11, TranslationBase.of(context).pharmacyTitle, TranslationBase.of(context).pharmacySubtitle, "assets/images/new/Pharmacy.svg", isLogin)); hmgServices.add(new HmgServices(12, TranslationBase.of(context).updateInsurance, TranslationBase.of(context).updateInsuranceSubtitle, "assets/images/new/update insurance card.svg", isLogin)); - hmgServices.add(new HmgServices(13, TranslationBase.of(context).myFamily, TranslationBase.of(context).Family_Files, "assets/images/new/my family.svg", isLogin)); + hmgServices.add(new HmgServices(13, TranslationBase.of(context).familyTitle, TranslationBase.of(context).familySubtitle, "assets/images/new/my family.svg", isLogin)); hmgServices.add(new HmgServices(14, TranslationBase.of(context).My_Child, TranslationBase.of(context).Vaccines, "assets/images/new/child vaccines.svg", isLogin)); hmgServices.add(new HmgServices(15, TranslationBase.of(context).Todo, TranslationBase.of(context).list, "assets/images/new/todo.svg", isLogin)); hmgServices.add(new HmgServices(16, TranslationBase.of(context).Blood, TranslationBase.of(context).Donation, "assets/images/new/blood donation.svg", isLogin)); - hmgServices.add(new HmgServices(17, TranslationBase.of(context).Health, TranslationBase.of(context).Calculator, "assets/images/new/health calculator.svg", isLogin)); - hmgServices.add(new HmgServices(18, TranslationBase.of(context).Health, TranslationBase.of(context).Converter, "assets/images/new/health converter.svg", isLogin)); - hmgServices.add(new HmgServices(19, TranslationBase.of(context).Smart, TranslationBase.of(context).Watches, "assets/images/new/smart watch.svg", isLogin)); - hmgServices.add(new HmgServices(20, TranslationBase.of(context).Parking, TranslationBase.of(context).Details, "assets/images/new/parking details.svg", isLogin)); + hmgServices.add(new HmgServices(17, TranslationBase.of(context).healthCalculatorTitle, TranslationBase.of(context).healthCalculatorSubtitle, "assets/images/new/health calculator.svg", isLogin)); + hmgServices.add(new HmgServices(18, TranslationBase.of(context).healthConvertersTitle, TranslationBase.of(context).healthConvertersSubtitle, "assets/images/new/health converter.svg", isLogin)); + hmgServices.add(new HmgServices(19, TranslationBase.of(context).smartWatches.split(" ")[0], TranslationBase.of(context).smartWatches.split(" ")[1], "assets/images/new/smart watch.svg", isLogin)); + hmgServices.add(new HmgServices(20, TranslationBase.of(context).parkingTitle2, TranslationBase.of(context).parkingSubtitle, "assets/images/new/parking details.svg", isLogin)); hmgServices.add(new HmgServices(21, TranslationBase.of(context).Virtual, TranslationBase.of(context).Tour, "assets/images/new/virtual tour.svg", isLogin)); - hmgServices.add(new HmgServices(22, TranslationBase.of(context).News, TranslationBase.of(context).Latest, "assets/images/new/latest news.svg", isLogin)); + hmgServices.add(new HmgServices(22, TranslationBase.of(context).latestNews.split(" ")[0], TranslationBase.of(context).latestNews.split(" ")[1], "assets/images/new/latest news.svg", isLogin)); } @override @@ -90,7 +90,7 @@ class _AllHabibMedicalSevicePage2State extends State child: Column( children: [ AspectRatio( - aspectRatio: 1.8, + aspectRatio: 1.9, child: Container( width: double.infinity, height: double.infinity, @@ -106,7 +106,7 @@ class _AllHabibMedicalSevicePage2State extends State ? Color(0xFFFECB50) : Color(0xFF122F48)), child: Padding( - padding: const EdgeInsets.all(30.0), + padding: const EdgeInsets.all(20.0), child: Stack( alignment: projectViewModel.isArabic ? Alignment.centerLeft : Alignment.centerRight, children: [ @@ -118,7 +118,7 @@ class _AllHabibMedicalSevicePage2State extends State child: Text( weather, style: TextStyle( - fontSize: 30, + fontSize: 24, letterSpacing: -0.83, fontWeight: FontWeight.bold, color: Colors.white, @@ -134,11 +134,11 @@ class _AllHabibMedicalSevicePage2State extends State color: Colors.white, ), ), - mFlex(1), + mFlex(0), Text( TranslationBase.of(context).healthWeatherIndicators, style: TextStyle( - fontSize: 16, + fontSize: 12, letterSpacing: -0.96, fontWeight: FontWeight.bold, color: Colors.white, @@ -147,7 +147,7 @@ class _AllHabibMedicalSevicePage2State extends State Text( TranslationBase.of(context).healthTipsBasedOnCurrentWeather, style: TextStyle( - fontSize: 12, + fontSize: 10, letterSpacing: -0.72, fontWeight: FontWeight.w600, color: Colors.white, @@ -163,7 +163,7 @@ class _AllHabibMedicalSevicePage2State extends State ); }, child: Padding( - padding: const EdgeInsets.only(top: 8, bottom: 8), + padding: const EdgeInsets.only(top: 0, bottom: 0), child: Text( TranslationBase.of(context).moreDetails, style: TextStyle(fontSize: 12, letterSpacing: -0.72, fontWeight: FontWeight.w600, color: Colors.white, decoration: TextDecoration.underline), diff --git a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart index b38e3f63..39264fe8 100644 --- a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart +++ b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart @@ -50,7 +50,7 @@ class _HospitalsPageState extends State { ? SingleChildScrollView( child: Column(children: [ AspectRatio( - aspectRatio: 1.8, + aspectRatio: 2.3, child: Container( width: double.infinity, height: double.infinity, @@ -66,7 +66,7 @@ class _HospitalsPageState extends State { ? Color(0xFFFECB50) : Color(0xFF122F48)), child: Padding( - padding: const EdgeInsets.all(30.0), + padding: const EdgeInsets.all(20.0), child: Stack( alignment: projectViewModel.isArabic ? Alignment.centerLeft : Alignment.centerRight, children: [ @@ -78,7 +78,7 @@ class _HospitalsPageState extends State { child: Text( weather, style: TextStyle( - fontSize: 30, + fontSize: 24, letterSpacing: -0.83, fontWeight: FontWeight.bold, color: Colors.white, @@ -94,11 +94,11 @@ class _HospitalsPageState extends State { color: Colors.white, ), ), - mFlex(1), + mFlex(0), Text( TranslationBase.of(context).healthWeatherIndicators, style: TextStyle( - fontSize: 16, + fontSize: 12, letterSpacing: -0.96, fontWeight: FontWeight.bold, color: Colors.white, @@ -107,7 +107,7 @@ class _HospitalsPageState extends State { Text( TranslationBase.of(context).healthTipsBasedOnCurrentWeather, style: TextStyle( - fontSize: 12, + fontSize: 10, letterSpacing: -0.72, fontWeight: FontWeight.w600, color: Colors.white, diff --git a/lib/pages/DrawerPages/notifications/notifications_page.dart b/lib/pages/DrawerPages/notifications/notifications_page.dart index 7b699467..6ae318c3 100644 --- a/lib/pages/DrawerPages/notifications/notifications_page.dart +++ b/lib/pages/DrawerPages/notifications/notifications_page.dart @@ -56,7 +56,26 @@ class NotificationsPage extends StatelessWidget { GifLoaderDialogUtils.hideDialog(context); }, child: Center( - child: Image.asset('assets/images/notf.png'), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Image.asset('assets/images/notf.png'), + Icon( + Icons.notifications_active, + color: CustomColors.accentColor, + size: 40, + ), + Padding( + padding: const EdgeInsets.only(left: 10.0, right: 10.0), + child: Text(TranslationBase.of(context).moreNotifications, style: TextStyle( + color: CustomColors.accentColor, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + decoration: TextDecoration.underline + )), + ), + ], + ), ), ); } @@ -154,91 +173,6 @@ class NotificationsPage extends StatelessWidget { ); }, itemCount: model.notifications.length + 1)), - // ListView( - // children: model.notifications - // .map( - // (notification) => InkWell( - // onTap: () async { - // if (!notification.isRead) { - // model.markAsRead(notification.id); - // } - // Navigator.push( - // context, - // FadePage( - // page: NotificationsDetailsPage( - // notification: notification, - // ))); - // }, - // child: Container( - // width: double.infinity, - // padding: EdgeInsets.all(8.0), - // decoration: BoxDecoration( - // color: notification.isRead ? CustomColors.white : CustomColors.accentColor.withOpacity(0.05), - // border: Border( - // left: BorderSide( - // color: notification.isRead ? Colors.grey[200] : CustomColors.accentColor, - // width: 5.0, - // ), - // ), - // ), - // child: Row( - // children: [ - // Expanded( - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Texts(DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(notification.createdOn)) + " " + DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(notification.createdOn), false)), - // SizedBox( - // height: 5, - // ), - // Row( - // children: [ - // Expanded( - // child: Texts(notification.message)), - // if (notification.messageType == "image") - // Icon(FontAwesomeIcons.images, color: CustomColors.grey,) - // ], - // ), - // SizedBox( - // height: 5, - // ), - // Divider( - // height: 5.0, - // color: CustomColors.grey2, - // ), - // ], - // ), - // ), - // ), - // ], - // ), - // ), - // ), - // ) - // .toList() - // ..add( - // InkWell( - // onTap: () async { - // GifLoaderDialogUtils.showMyDialog(context); - // currentIndex++; - // GetNotificationsRequestModel - // getNotificationsRequestModel = - // new GetNotificationsRequestModel( - // currentPage: currentIndex, - // pagingSize: 14, - // notificationStatusID: 2); - // - // await model.getNotifications( - // getNotificationsRequestModel, context); - // GifLoaderDialogUtils.hideDialog(context); - // }, - // child: Center( - // child: Image.asset('assets/images/notf.png'), - // ), - // ), - // )), ); } } diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 08a7971e..21a82f6a 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -53,14 +53,14 @@ class _HomePageFragment2State extends State { initialiseHmgServices(bool isLogin) { hmgServices.clear(); - hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); + hmgServices.add(new HmgServices(0, TranslationBase.of(context).liveCareTitle, TranslationBase.of(context).liveCareSubtitle, "assets/images/new/Live_Care.svg", isLogin)); hmgServices.add(new HmgServices(1, TranslationBase.of(context).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/covid_test_drive_thru.svg", isLogin)); hmgServices.add(new HmgServices(2, TranslationBase.of(context).onlinePayment, TranslationBase.of(context).onlinePaymentSubtitle, "assets/images/new/paymentMethods.png", isLogin)); hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); hmgServices.add(new HmgServices(4, TranslationBase.of(context).cmcTitle, TranslationBase.of(context).cmcSubtitle, "assets/images/new/comprehensive_checkup.svg", isLogin)); hmgServices.add(new HmgServices(5, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); hmgServices.add(new HmgServices(6, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); - hmgServices.add(new HmgServices(7, "H\u2082O", TranslationBase.of(context).dailyWater, "assets/images/new/h2o.svg", isLogin)); + hmgServices.add(new HmgServices(7, TranslationBase.of(context).waterTitle, TranslationBase.of(context).waterSubtitle, "assets/images/new/h2o.svg", isLogin)); hmgServices.add(new HmgServices(8, TranslationBase.of(context).findUs, TranslationBase.of(context).reachUs, "assets/images/new/reach_us.svg", isLogin)); } @@ -496,7 +496,7 @@ class _HomePageFragment2State extends State { Container( width: double.infinity, height: double.infinity, - padding: EdgeInsets.all(SizeConfig.widthMultiplier * 3.4), + padding: EdgeInsets.all(SizeConfig.widthMultiplier * 3.3), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, @@ -515,7 +515,7 @@ class _HomePageFragment2State extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - TranslationBase.of(context).onlinePharmacy, + TranslationBase.of(context).pharmacyTitle, style: TextStyle( color: Colors.black, fontSize: 14, @@ -526,7 +526,7 @@ class _HomePageFragment2State extends State { ), projectViewModel.isArabic ? mHeight(5) : Container(), Text( - TranslationBase.of(context).ecommerceSolution, + TranslationBase.of(context).pharmacySubtitle, style: TextStyle( color: Colors.black, fontSize: 9, diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart index 2245872b..9f395cad 100644 --- a/lib/pages/landing/home_page_2.dart +++ b/lib/pages/landing/home_page_2.dart @@ -66,7 +66,7 @@ class _HomePageState2 extends State { } else { GifLoaderDialogUtils.showMyDialog(context); await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if (pharmacyModuleViewModel.error.isNotEmpty) { + if (!pharmacyModuleViewModel.error.isNotEmpty) { await pharmacyModuleViewModel.createUser().then((value) { GifLoaderDialogUtils.hideDialog(context); Navigator.push(context, FadePage(page: LandingPagePharmacy())); diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 2bb0e1d0..628886db 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -279,7 +279,7 @@ class _Login extends State { ConfirmDialog.closeAlertDialog(context), Navigator.of(context).push(FadePage(page: Register())), }, - cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); + cancelFunction: () => {}); dialog.showAlertDialog(context); }); // SMSOTP.showLoadingDialog(context, false), diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 76c09e00..d8201c65 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1761,7 +1761,9 @@ class TranslationBase { String get referralNumber => localizedValues['referralNumber'][locale.languageCode]; String get needPrescription => localizedValues['needPrescription'][locale.languageCode]; + String get outOfStockMsg => localizedValues['outOfStockMsg'][locale.languageCode]; + String get requestID => localizedValues['requestID'][locale.languageCode]; String get OrderStatus => localizedValues['OrderStatus'][locale.languageCode]; @@ -1799,10 +1801,11 @@ class TranslationBase { String get quantitySize => localizedValues['quantitySize'][locale.languageCode]; String get addToCart => localizedValues['addToCart'][locale.languageCode]; - String get addToWishlist => - localizedValues['addToWishlist'][locale.languageCode]; - String get removeFromWishlist => - localizedValues['removeFromWishlist'][locale.languageCode]; + + String get addToWishlist => localizedValues['addToWishlist'][locale.languageCode]; + + String get removeFromWishlist => localizedValues['removeFromWishlist'][locale.languageCode]; + String get buyNow => localizedValues['buyNow'][locale.languageCode]; String get quantityShortcut => localizedValues['quantityShortcut'][locale.languageCode]; @@ -2475,11 +2478,46 @@ class TranslationBase { String get Latest => localizedValues["Latest"][locale.languageCode]; String get Tour => localizedValues["Tour"][locale.languageCode]; + String get mostViewed => localizedValues["mostViewed"][locale.languageCode]; + String get newProducts => localizedValues["newProducts"][locale.languageCode]; String get paymentSelected => localizedValues["paymentSelected"][locale.languageCode]; + String get moreNotifications => localizedValues["moreNotifications"][locale.languageCode]; + + String get familyTitle => localizedValues["familyTitle"][locale.languageCode]; + + String get familySubtitle => localizedValues["familySubtitle"][locale.languageCode]; + + String get liveCareTitle => localizedValues["liveCareTitle"][locale.languageCode]; + + String get liveCareSubtitle => localizedValues["liveCareSubtitle"][locale.languageCode]; + + String get pharmacyTitle => localizedValues["pharmacyTitle"][locale.languageCode]; + + String get pharmacySubtitle => localizedValues["pharmacySubtitle"][locale.languageCode]; + + String get parkingTitle2 => localizedValues["parkingTitle2"][locale.languageCode]; + + String get parkingSubtitle => localizedValues["ParkingSubtitle"][locale.languageCode]; + + String get healthCalculatorTitle => localizedValues["healthCalculatorTitle"][locale.languageCode]; + + String get healthCalculatorSubtitle => localizedValues["healthCalculatorSubtitle"][locale.languageCode]; + + String get waterTitle => localizedValues["waterTitle"][locale.languageCode]; + + String get waterSubtitle => localizedValues["waterSubtitle"][locale.languageCode]; + + String get medicalFileTitle2 => localizedValues["medicalFileTitle2"][locale.languageCode]; + + String get medicalFileSubtitle => localizedValues["medicalFileSubtitle"][locale.languageCode]; + + String get healthConvertersTitle => localizedValues["healthConvertersTitle"][locale.languageCode]; + + String get healthConvertersSubtitle => localizedValues["healthConvertersSubtitle"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/bottom_options/BottomSheet.dart b/lib/widgets/bottom_options/BottomSheet.dart index 7bbadd8c..f0016fc5 100644 --- a/lib/widgets/bottom_options/BottomSheet.dart +++ b/lib/widgets/bottom_options/BottomSheet.dart @@ -23,7 +23,7 @@ class ImageOptions { icon: FeatherIcons.image, onTap: () async { File _image = - await ImagePicker.pickImage(source: ImageSource.gallery); + await ImagePicker.pickImage(source: ImageSource.gallery, imageQuality: 50); String fileName = _image.path; final bytes = File(fileName).readAsBytesSync(); String base64Encode = base64.encode(bytes); @@ -37,7 +37,7 @@ class ImageOptions { icon: FeatherIcons.camera, onTap: () async { File _image = - await ImagePicker.pickImage(source: ImageSource.camera); + await ImagePicker.pickImage(source: ImageSource.camera, imageQuality: 50); String fileName = _image.path; final bytes = File(fileName).readAsBytesSync(); String base64Encode = base64.encode(bytes); From 2032053cb755e2791c35ed1f1f3417525bf6157d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 21 Oct 2021 17:50:37 +0300 Subject: [PATCH 07/60] Working on Health data --- lib/config/localized_values.dart | 3 + lib/core/service/client/base_app_client.dart | 2 +- .../SmartWatch/WeeklyStepsResModel.dart | 42 ++ .../SmartWatch/YearlyStepsResModel.dart | 3 +- .../Steps/stepsTracker.dart | 426 ++++++++++++++++++ .../health_data_list.dart | 291 +++++------- .../smart_watch_instructions.dart | 21 +- .../smart_watch_health_data/stepsTracker.dart | 249 ---------- lib/uitl/translations_delegate_base.dart | 6 + 9 files changed, 612 insertions(+), 431 deletions(-) create mode 100644 lib/models/SmartWatch/WeeklyStepsResModel.dart create mode 100644 lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart delete mode 100644 lib/pages/medical/smart_watch_health_data/stepsTracker.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index b4c0df07..7c13c84a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1578,4 +1578,7 @@ const Map localizedValues = { "medicalFileSubtitle": {"en": "Details", "ar": "ملفي الطبي"}, "healthConvertersTitle": {"en": "Health", "ar": "تحويل"}, "healthConvertersSubtitle": {"en": "Converters", "ar": "القياسات"}, + "syncHealthData": { "en": "Sync Health Data", "ar": "مزامنة البيانات الصحية" }, + "steps": { "en": "Steps", "ar": "الخطوات" }, + "avgSteps": { "en": "Average Steps", "ar": "متوسط الخطوات" }, }; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 0dd5c750..dc8f5288 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -115,7 +115,7 @@ class BaseAppClient { } // body['PatientID'] = 1018977; - // body['TokenID'] = "@dm!n"; + body['TokenID'] = "@dm!n"; print("URL : $url"); final jsonBody = json.encode(body); diff --git a/lib/models/SmartWatch/WeeklyStepsResModel.dart b/lib/models/SmartWatch/WeeklyStepsResModel.dart new file mode 100644 index 00000000..9c1f2da5 --- /dev/null +++ b/lib/models/SmartWatch/WeeklyStepsResModel.dart @@ -0,0 +1,42 @@ +class WeeklyStepsResModel { + int iD; + int patientID; + int medCategoryID; + int medSubCategoryID; + num value; + String machineDate; + bool patientOutSA; + dynamic notes; + bool isActive; + String createdOn; + + WeeklyStepsResModel({this.iD, this.patientID, this.medCategoryID, this.medSubCategoryID, this.value, this.machineDate, this.patientOutSA, this.notes, this.isActive, this.createdOn}); + + WeeklyStepsResModel.fromJson(Map json) { + iD = json['ID']; + patientID = json['PatientID']; + medCategoryID = json['MedCategoryID']; + medSubCategoryID = json['MedSubCategoryID']; + value = num.tryParse(json['Value']).toInt(); + machineDate = json['MachineDate']; + patientOutSA = json['PatientOutSA']; + notes = json['Notes']; + isActive = json['IsActive']; + createdOn = json['CreatedOn']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['PatientID'] = this.patientID; + data['MedCategoryID'] = this.medCategoryID; + data['MedSubCategoryID'] = this.medSubCategoryID; + data['Value'] = this.value; + data['MachineDate'] = this.machineDate; + data['PatientOutSA'] = this.patientOutSA; + data['Notes'] = this.notes; + data['IsActive'] = this.isActive; + data['CreatedOn'] = this.createdOn; + return data; + } +} diff --git a/lib/models/SmartWatch/YearlyStepsResModel.dart b/lib/models/SmartWatch/YearlyStepsResModel.dart index 728633d9..c98fff27 100644 --- a/lib/models/SmartWatch/YearlyStepsResModel.dart +++ b/lib/models/SmartWatch/YearlyStepsResModel.dart @@ -1,5 +1,5 @@ class YearlyStepsResModel { - double valueSum; + num valueSum; int medCategoryID; int month; String monthName; @@ -21,6 +21,7 @@ class YearlyStepsResModel { monthName = json['MonthName']; patientID = json['PatientID']; year = json['Year']; + valueSum = valueSum != null ? valueSum.toInt() : valueSum; } Map toJson() { diff --git a/lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart new file mode 100644 index 00000000..f879886a --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart @@ -0,0 +1,426 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/WeeklyStepsResModel.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/YearlyStepsResModel.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class StepsTracker extends StatefulWidget { + @override + _StepsTrackerState createState() => _StepsTrackerState(); +} + +class _StepsTrackerState extends State with SingleTickerProviderStateMixin { + TabController _tabController; + + ProjectViewModel projectViewModel; + + int weeklyStatsAvgValue = 0; + int monthlyStatsAvgValue = 0; + int yearlyStatsAvgValue = 0; + + int avgWeeklyStepsValue = 0; + int weeklyDataLength = 0; + + int avgMonthlyStepsValue = 0; + int monthlyDataLength = 0; + + int avgYearlyStepsValue = 0; + int yearlyDataLength = 0; + + List weekyStepsList = List(); + List yearlyStepsList = List(); + + List weeklyTimeSeriesData = []; + List monthlyTimeSeriesData = []; + List yearlyTimeSeriesData = []; + + bool isWeeklyDataLoaded = false; + bool isMonthlyDataLoaded = false; + bool isYearlyDataLoaded = false; + + @override + void initState() { + _tabController = new TabController(length: 3, vsync: this); + WidgetsBinding.instance.addPostFrameCallback((_) { + // getYearlyStepsData(); + getWeeklyStepsData(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).steps, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + body: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 0, bottom: 0, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Tab(text: TranslationBase.of(context).weekly), + Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).yearly), + ], + onTap: (value) { + if (value == 0) { + getWeeklyStepsData(); + } else if (value == 1) { + } else { + getYearlyStepsData(); + } + }, + ), + Expanded( + child: new TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + isWeeklyDataLoaded ? getWeeklyStepsDetails() : Container(), + isMonthlyDataLoaded ? getMonthlyStepsDetails() : Container(), + isYearlyDataLoaded ? getYearlyStepsDetails() : Container() + ], + controller: _tabController, + ), + ), + ], + ), + ); + } + + getWeeklyStepsData() { + avgWeeklyStepsValue = 0; + weeklyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(6, 1, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['Med_GetYearStepsTransactionsStsList']); + weekyStepsList.clear(); + res['Med_GetWeekStepsTransactionsStsList'].forEach((element) { + weekyStepsList.add(new WeeklyStepsResModel.fromJson(element)); + if (element['Value'] != null) { + num value = num.tryParse(element['Value'] ?? "0"); + avgWeeklyStepsValue += value.toInt(); + weeklyDataLength++; + } + }); + generateWeekData(); + setState(() { + weeklyStatsAvgValue = avgWeeklyStepsValue ~/ weeklyDataLength; + isWeeklyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getMonthlyStepsData() {} + + getYearlyStepsData() { + avgYearlyStepsValue = 0; + yearlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(6, 3, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['Med_GetYearStepsTransactionsStsList']); + yearlyStepsList.clear(); + res['Med_GetYearStepsTransactionsStsList'].forEach((element) { + yearlyStepsList.add(new YearlyStepsResModel.fromJson(element)); + if (element['ValueSum'] != null) { + num value = element['ValueSum']; + avgYearlyStepsValue += value.toInt(); + yearlyDataLength++; + } + }); + generateYearData(); + setState(() { + yearlyStatsAvgValue = avgYearlyStepsValue ~/ yearlyDataLength; + isYearlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + generateWeekData() { + if (weekyStepsList.length > 0) { + weeklyTimeSeriesData.clear(); + weekyStepsList.forEach( + (element) { + weeklyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.value != null ? element.value : 0.0, + ), + ); + }, + ); + } + } + + generateYearData() { + if (yearlyStepsList.length > 0) { + yearlyTimeSeriesData.clear(); + yearlyStepsList.forEach( + (element) { + yearlyTimeSeriesData.add( + TimeSeriesSales2( + new DateTime(element.year, element.month, 1), + element.valueSum != null ? double.tryParse(element.valueSum.toString()) : 0.0, + ), + ); + }, + ); + } + } + + getWeeklyStepsDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: weeklyTimeSeriesData, + indexes: weeklyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgSteps, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(weeklyStatsAvgValue.toString() + " " + TranslationBase.of(context).steps, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + weekyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataWeekly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + getMonthlyStepsDetails() { + return Container( + child: Text("Monthly"), + ); + } + + getYearlyStepsDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: yearlyTimeSeriesData, + indexes: yearlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgSteps, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).steps, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + yearlyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullData(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + List fullData(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).steps), + ], + ), + ); + yearlyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + new DateTime(step.year, step.month, 1), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.valueSum.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + + List fullDataWeekly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).steps), + ], + ), + ); + weekyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.value.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } +} diff --git a/lib/pages/medical/smart_watch_health_data/health_data_list.dart b/lib/pages/medical/smart_watch_health_data/health_data_list.dart index cbfc1c5c..12dd7ee1 100644 --- a/lib/pages/medical/smart_watch_health_data/health_data_list.dart +++ b/lib/pages/medical/smart_watch_health_data/health_data_list.dart @@ -1,6 +1,9 @@ -import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/stepsTracker.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; + // import 'package:fit_kit/fit_kit.dart'; import 'package:flutter/material.dart'; @@ -10,7 +13,6 @@ class HealthDataList extends StatefulWidget { } class _HealthDataListState extends State { - // List dataTypes = List(); @override @@ -27,191 +29,134 @@ class _HealthDataListState extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: "Smartwatches", - isShowAppBar: true, - body: Container( - height: MediaQuery - .of(context) - .size - .height, - margin: EdgeInsets.all(20.0), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - child: Image.asset( - "assets/images/SmartWatches/heartrate_icon.png", - width: 60.0, - height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Heart Rate", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - Divider( - color: Colors.grey[500], - ), - Row( - children: [ - Container( - child: Image.asset( - "assets/images/SmartWatches/sleep_data.png", - width: 60.0, - height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Sleep Data", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - Divider( - color: Colors.grey[500], - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: StepsTracker(), - ), - ); - }, - child: Row( - children: [ - Container( - child: Image.asset( - "assets/images/SmartWatches/heartrate_icon.png", - width: 60.0, - height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Steps", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + appBarTitle: TranslationBase.of(context).smartWatches, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + body: Container( + height: MediaQuery.of(context).size.height, + margin: EdgeInsets.all(20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), ), - ), - Divider( - color: Colors.grey[500], - ), - Row( - children: [ - Container( - child: Image.asset( - "assets/images/SmartWatches/heartrate_icon.png", - width: 60.0, - height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Distance", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text("Heart Rate", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + Divider( + color: Colors.grey[500], + ), + Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/sleep_data.png", width: 60.0, height: 60.0), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text("Sleep Data", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + Divider( + color: Colors.grey[500], + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: StepsTracker(), ), - ], - ), - Divider( - color: Colors.grey[500], - ), - Row( + ); + }, + child: Row( children: [ Container( - child: Image.asset( - "assets/images/SmartWatches/heartrate_icon.png", - width: 60.0, - height: 60.0), + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), ), Container( margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Energy", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text("Steps", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), ], ), - Divider( - color: Colors.grey[500], - ), - ], - ), - ), - ), - bottomSheet: Container( - width: double.infinity, - height: MediaQuery - .of(context) - .size - .height * 0.1, - color: Colors.grey[100], - child: Column( - children: [ + ), Divider( - color: Colors.transparent, + color: Colors.grey[500], ), - InkWell( - onTap: () { - print("ReadLast"); - // readLast(); - }, - child:Container( - height: (MediaQuery - .of(context) - .size - .height/2)*0.12, - width: MediaQuery - .of(context) - .size - .width * 0.8, - decoration: BoxDecoration( - color: Colors.grey[800], - borderRadius: BorderRadius.circular(6.0), + Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), ), - child: Container( - padding: EdgeInsets.only(top: 10.0), - child: Text( - 'Sync Health Data' , textAlign: TextAlign.center,style: TextStyle( - color: Colors.white , fontSize: 18.0 - ), - ), - ),),), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text("Distance", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + Divider( + color: Colors.grey[500], + ), + Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text("Energy", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + Divider( + color: Colors.grey[500], + ), ], ), - )); + ), + ), + bottomSheet: Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(20.0), + child: DefaultButton(TranslationBase.of(context).syncHealthData, () { + print("ReadLast"); + // readLast(); + }), + ), + ), + ); } - - // void readLast() async { - // print("ReadLast"); - // final result = await FitKit.readLast(DataType.DISTANCE); - // print(result); - // print(result); - // } - // - // void readAll() async { - // if (await FitKit.requestPermissions(dataTypes)) { - // for (DataType type in dataTypes) { - // final results = await FitKit.read( - // type, - // dateFrom: DateTime.now().subtract(Duration(days: 7)), - // dateTo: DateTime.now(), - // limit: 100, - // ); - // print(results); - // print(results.length); - // } - // readLast(); - // } - // } -} \ No newline at end of file +// void readLast() async { +// print("ReadLast"); +// final result = await FitKit.readLast(DataType.DISTANCE); +// print(result); +// print(result); +// } +// +// void readAll() async { +// if (await FitKit.requestPermissions(dataTypes)) { +// for (DataType type in dataTypes) { +// final results = await FitKit.read( +// type, +// dateFrom: DateTime.now().subtract(Duration(days: 7)), +// dateTo: DateTime.now(), +// limit: 100, +// ); +// print(results); +// print(results.length); +// } +// readLast(); +// } +// } +} diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index eb8e916e..c550fa08 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -9,6 +9,7 @@ import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchI import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -37,9 +38,11 @@ class _SmartWatchInstructionsState extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: "Sync Health Data", + appBarTitle: TranslationBase.of(context).smartWatches, isShowAppBar: true, isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, description: TranslationBase.of(context).infoHealthData, imagesInfo: [ ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/0.png'), @@ -56,9 +59,10 @@ class _SmartWatchInstructionsState extends State { return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Container( - margin: EdgeInsets.only(top: 10.0), + Flexible( + // margin: EdgeInsets.only(top: 10.0), child: CarouselSlider( carouselController: buttonCarouselController, options: CarouselOptions( @@ -85,8 +89,7 @@ class _SmartWatchInstructionsState extends State { child: Text("Supported Smartwatches", style: TextStyle( fontSize: 22.0, - fontWeight: FontWeight.bold, - fontFamily: "WorkSans")), + fontWeight: FontWeight.bold)), ), Container( child: Row( @@ -371,7 +374,7 @@ class _SmartWatchInstructionsState extends State { ), Container( margin: EdgeInsets.fromLTRB( - 15.0, 110.0, 15.0, 15.0), + 15.0, 80.0, 15.0, 15.0), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: @@ -854,6 +857,10 @@ class _SmartWatchInstructionsState extends State { _openHealthDataList() { Navigator.push( - context, MaterialPageRoute(builder: (context) => HealthDataList())); + context, + FadePage( + page: HealthDataList(), + ), + ); } } diff --git a/lib/pages/medical/smart_watch_health_data/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/stepsTracker.dart deleted file mode 100644 index 3fe1a4ba..00000000 --- a/lib/pages/medical/smart_watch_health_data/stepsTracker.dart +++ /dev/null @@ -1,249 +0,0 @@ -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:diplomaticquarterapp/models/SmartWatch/YearlyStepsResModel.dart'; -import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:flutter/material.dart'; - -class StepsTracker extends StatefulWidget { - @override - _StepsTrackerState createState() => _StepsTrackerState(); -} - -class _StepsTrackerState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - - int weeklyStatsAvgValue = 0; - int monthlyStatsAvgValue = 0; - int yearlyStatsAvgValue = 0; - - int avgStepsValue = 0; - int dataLength = 0; - - List yearlyStepsList = List(); - - List yearlyTimeSeriesData = []; - - bool isDataLoaded = false; - - @override - void initState() { - _tabController = new TabController(length: 3, vsync: this); - WidgetsBinding.instance.addPostFrameCallback((_) { - getYearlyStepsData(); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: "Steps", - isShowDecPage: false, - body: Container( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TabBar( - tabs: [ - Tab(text: TranslationBase.of(context).weekly), - Tab(text: TranslationBase.of(context).monthly), - Tab(text: TranslationBase.of(context).yearly), - ], - controller: _tabController, - ), - Expanded( - child: new TabBarView( - physics: NeverScrollableScrollPhysics(), - children: [ - isDataLoaded ? getWeeklyStepsDetails() : Container(), - isDataLoaded ? getMonthlyStepsDetails() : Container(), - isDataLoaded ? getYearlyStepsDetails() : Container() - ], - controller: _tabController, - ), - ), - ], - ), - ), - ); - } - - getYearlyStepsData() { - avgStepsValue = 0; - dataLength = 0; - - DoctorsListService service = new DoctorsListService(); - GifLoaderDialogUtils.showMyDialog(context); - service.getPatientHealthDataStats(6, 3, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - print(res['Med_GetYearStepsTransactionsStsList']); - yearlyStepsList.clear(); - res['Med_GetYearStepsTransactionsStsList'].forEach((element) { - print('in forEach'); - yearlyStepsList.add(new YearlyStepsResModel.fromJson(element)); - if (element['ValueSum'] != null) { - double value = element['ValueSum']; - avgStepsValue += value.toInt(); - dataLength++; - } - }); - print("innnnnnnnnnnnnnnnn"); - print(avgStepsValue); - print(dataLength); - setState(() { - yearlyStatsAvgValue = avgStepsValue ~/ dataLength; - isDataLoaded = true; - }); - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); - // AppToast.showErrorToast(message: err); - print(err); - }); - } - - generateData() { - if (yearlyStepsList.length > 0) { - yearlyTimeSeriesData.clear(); - yearlyStepsList.forEach( - (element) { - yearlyTimeSeriesData.add( - TimeSeriesSales( - new DateTime(element.year, element.month, 1), - element.valueSum != null ? element.valueSum.toInt() : 0, - ), - ); - }, - ); - yearlyTimeSeriesData.forEach((element) { - print(element.sales); - print(element.time); - }); - } - return [ - new charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (TimeSeriesSales sales, _) => sales.time, - measureFn: (TimeSeriesSales sales, _) => sales.sales, - data: yearlyTimeSeriesData, - ) - ]; - } - - getWeeklyStepsDetails() { - return Container( - child: Text("Weekly"), - ); - } - - getMonthlyStepsDetails() { - return Container( - child: Text("Monthly"), - ); - } - - getYearlyStepsDetails() { - return Container( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - child: AppTimeSeriesChart( - seriesList: generateData(), - chartName: "Steps", - startDate: DateTime( - yearlyStepsList[0].year, yearlyStepsList[0].month, 1), - endDate: DateTime( - yearlyStepsList[yearlyStepsList.length - 1].year, - yearlyStepsList[yearlyStepsList.length - 1].month, - 1), - ), - ), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(color: Colors.grey[400], width: 0.6)), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), - child: - Text("Average Steps", style: TextStyle(fontSize: 18.0)), - ), - Container( - margin: EdgeInsets.only(bottom: 10.0), - child: Text(yearlyStatsAvgValue.toString() + " Steps", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - ), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Divider( - color: Colors.grey[500], - ), - ), - Container( - transform: Matrix4.translationValues(0.0, -10.0, 0.0), - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 5.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("History", style: TextStyle(fontSize: 14.0)), - Row( - children: [ - Text("view more", style: TextStyle(fontSize: 14.0)), - Container( - margin: EdgeInsets.only(left: 3.0, right: 3.0), - transform: Matrix4.translationValues(0.0, 1.5, 0.0), - width: 30.0, - height: 30.0, - child: Image.asset( - "assets/images/new-design/view_more.png", - fit: BoxFit.contain), - ), - ], - ), - ], - ), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 5.0), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(color: Colors.grey[400], width: 0.6)), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), - child: Text("Date", - style: TextStyle( - fontSize: 18.0, fontWeight: FontWeight.bold)), - ), - Container( - padding: EdgeInsets.fromLTRB(30.0, 0.0, 30.0, 0.0), - child: Text("Steps", style: TextStyle(fontSize: 18.0)), - ), - ], - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index d8201c65..aaf92cc7 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2518,6 +2518,12 @@ class TranslationBase { String get healthConvertersTitle => localizedValues["healthConvertersTitle"][locale.languageCode]; String get healthConvertersSubtitle => localizedValues["healthConvertersSubtitle"][locale.languageCode]; + + String get syncHealthData => localizedValues["syncHealthData"][locale.languageCode]; + + String get steps => localizedValues["steps"][locale.languageCode]; + + String get avgSteps => localizedValues["avgSteps"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 745b167c47151e234e3a3a22e1b963ffcc95ecb7 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 21 Oct 2021 18:05:59 +0300 Subject: [PATCH 08/60] register --- lib/pages/login/register.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index f7def7c8..b93e4e55 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -150,7 +150,9 @@ class _Register extends State { )), bottomSheet: Container( width: double.maxFinite, - height: 80.0, + // height: 80.0, + color: Colors.white, + margin: EdgeInsets.only(bottom: 50.0), child: Row( children: [ Expanded( From e494c9304db55e962d6ccfbd1311ba272392f8ee Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Sun, 24 Oct 2021 15:54:03 +0300 Subject: [PATCH 09/60] fixed issues --- .../model/pharmacies/PharmacyProduct.dart | 2 +- lib/core/model/pharmacies/orders_model.dart | 10 +- .../pharmacies/ProductCheckTypeWidget.dart | 1 + .../pharmacies/widgets/ProductOrderItem.dart | 3 +- lib/pages/pharmacy/order/Order.dart | 587 +++++++++--------- lib/pages/pharmacy/order/OrderDetails.dart | 3 +- .../bottom_nav_pharmacy_home_item.dart | 23 +- .../pharmacy/bottom_nav_pharmacy_item.dart | 19 +- lib/widgets/pharmacy/product_tile.dart | 46 +- 9 files changed, 359 insertions(+), 335 deletions(-) diff --git a/lib/core/model/pharmacies/PharmacyProduct.dart b/lib/core/model/pharmacies/PharmacyProduct.dart index dbef5737..8f846480 100644 --- a/lib/core/model/pharmacies/PharmacyProduct.dart +++ b/lib/core/model/pharmacies/PharmacyProduct.dart @@ -20,7 +20,7 @@ class PharmacyProduct { bool allowCustomerReviews; int approvedRatingSum; int notApprovedRatingSum; - int approvedTotalReviews; + dynamic approvedTotalReviews; int notApprovedTotalReviews; dynamic sku; bool isRx; diff --git a/lib/core/model/pharmacies/orders_model.dart b/lib/core/model/pharmacies/orders_model.dart index 0ad94767..cef20c30 100644 --- a/lib/core/model/pharmacies/orders_model.dart +++ b/lib/core/model/pharmacies/orders_model.dart @@ -24,7 +24,7 @@ class OrdersModel { class Orders { String id; int productCount; - double orderTotal; + dynamic orderTotal; String createdOnUtc; int orderStatusId; String orderStatus; @@ -32,9 +32,9 @@ class Orders { bool canCancel; bool canRefund; dynamic customerId; - double orderSubtotalExclTax; + dynamic orderSubtotalExclTax; dynamic orderShippingExclTax; - double orderTax; + dynamic orderTax; Orders( @@ -64,9 +64,9 @@ class Orders { canCancel = json['can_cancel']; canRefund = json['can_refund']; customerId = json['customer_id']; - orderSubtotalExclTax= json["order_subtotal_excl_tax"].toDouble(); + orderSubtotalExclTax= json["order_subtotal_excl_tax"]; orderShippingExclTax= json["order_shipping_excl_tax"]; - orderTax= json["order_tax"].toDouble(); + orderTax= json["order_tax"]; }catch(e){ print(e); } diff --git a/lib/pages/pharmacies/ProductCheckTypeWidget.dart b/lib/pages/pharmacies/ProductCheckTypeWidget.dart index aac971a0..2b88d30a 100644 --- a/lib/pages/pharmacies/ProductCheckTypeWidget.dart +++ b/lib/pages/pharmacies/ProductCheckTypeWidget.dart @@ -32,6 +32,7 @@ class _ProductCheckTypeWidgetState extends State { : widget.model.wishListList[index].product.name, productPrice: widget.model.wishListList[index].subtotal, productRate: double.parse(widget.model.wishListList[index].subtotalVatRate), + approvedTotalReviews:widget.model.wishListList[index].product.approvedTotalReviews, productImage: widget.model.wishListList[index].product.images[0].src, productID: widget.model.wishListList[index].product.id, onDelete: deleteWishListItem, diff --git a/lib/pages/pharmacies/widgets/ProductOrderItem.dart b/lib/pages/pharmacies/widgets/ProductOrderItem.dart index cb7c59fd..11976175 100644 --- a/lib/pages/pharmacies/widgets/ProductOrderItem.dart +++ b/lib/pages/pharmacies/widgets/ProductOrderItem.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; class ProductOrderItem extends StatefulWidget { @@ -39,7 +40,7 @@ class _ProductOrderItemState extends State { leading: InkWell( onTap: () => {widget.deleteCartItems()}, child: Icon( - Icons.delete_outline_sharp, + FontAwesomeIcons.trashAlt,size: 15, color: Colors.grey.shade700, ), ), diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 7ffcbdbd..4e4a0cc9 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -70,6 +70,7 @@ class _OrderPageState extends State TabBar( labelPadding: EdgeInsets.only(left: 3.0, right: 3.0), labelColor: Colors.black, + indicatorColor: Colors.green, tabs: [ Tab(text: TranslationBase.of(context).delivered), Tab(text: TranslationBase.of(context).processing), @@ -127,86 +128,86 @@ class _OrderPageState extends State return Container( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderNumber, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + deliveredOrderList[ + index]), + )); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - Container( - child: Text( - deliveredOrderList[index] - .id - .toString(), - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + Container( + child: Text( + deliveredOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - ], - ), - SizedBox( - height: 5, - ), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderDate, - style: TextStyle( - fontSize: 14.0, + ], + ), + SizedBox( + height: 5, + ), + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - Container( - child: Text( - deliveredOrderList[index] - .createdOnUtc - .toString() - .substring(0, 10), - style: TextStyle( - fontSize: 14.0, + Container( + child: Text( + deliveredOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: OrderDetailsPage( - orderModel: - deliveredOrderList[ - index]), - )); - }, + Container( + margin: EdgeInsets.all(8.0), child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -215,8 +216,8 @@ class _OrderPageState extends State width: 20, ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -394,85 +395,85 @@ class _OrderPageState extends State return Container( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderNumber, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + processingOrderList[ + index]))); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - Container( - child: Text( - processingOrderList[index] - .id - .toString(), - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + Container( + child: Text( + processingOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - ], - ), - SizedBox( - height: 5, - ), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderDate, - style: TextStyle( - fontSize: 14.0, + ], + ), + SizedBox( + height: 5, + ), + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - Container( - child: Text( - processingOrderList[index] - .createdOnUtc - .toString() - .substring(0, 10), - style: TextStyle( - fontSize: 14.0, + Container( + child: Text( + processingOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: OrderDetailsPage( - orderModel: - processingOrderList[ - index]))); - }, + Container( + margin: EdgeInsets.all(8.0), child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -481,8 +482,8 @@ class _OrderPageState extends State width: 20, ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -837,87 +838,87 @@ class _OrderPageState extends State child: SingleChildScrollView( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: - EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderNumber, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + pendingOrderList[ + index]))); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - Container( - child: Text( - pendingOrderList[index] - .id - .toString(), - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + Container( + child: Text( + pendingOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - ], - ), - SizedBox( - height: 5, - ), - Row( - children: [ - Container( - margin: - EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderDate, - style: TextStyle( - fontSize: 14.0, + ], + ), + SizedBox( + height: 5, + ), + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - Container( - child: Text( - pendingOrderList[index] - .createdOnUtc - .toString() - .substring(0, 10), - style: TextStyle( - fontSize: 14.0, + Container( + child: Text( + pendingOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: OrderDetailsPage( - orderModel: - pendingOrderList[ - index]))); - }, + Container( + margin: EdgeInsets.all(8.0), child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -926,8 +927,8 @@ class _OrderPageState extends State width: 20, ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -1106,87 +1107,87 @@ class _OrderPageState extends State child: SingleChildScrollView( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: - EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderNumber, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + cancelledOrderList[ + index]))); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - Container( - child: Text( - cancelledOrderList[index] - .id - .toString(), - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, + Container( + child: Text( + cancelledOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), - ), - ], - ), - SizedBox( - height: 5, - ), - Row( - children: [ - Container( - margin: - EdgeInsets.only(right: 5), - child: Text( - TranslationBase.of(context) - .orderDate, - style: TextStyle( - fontSize: 14.0, + ], + ), + SizedBox( + height: 5, + ), + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - Container( - child: Text( - cancelledOrderList[index] - .createdOnUtc - .toString() - .substring(0, 10), - style: TextStyle( - fontSize: 14.0, + Container( + child: Text( + cancelledOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: OrderDetailsPage( - orderModel: - cancelledOrderList[ - index]))); - }, + Container( + margin: EdgeInsets.all(8.0), child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -1195,8 +1196,8 @@ class _OrderPageState extends State width: 20, ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 1275042a..aadb5a90 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -321,8 +321,7 @@ class _OrderDetailsPageState extends State { margin: EdgeInsets.only(bottom: 10.0, top: 10.0), child: Text( model.orderListModel[0].paymentName - .toString() - .substring(12), + .toString(), style: TextStyle( fontSize: 13.0, fontWeight: FontWeight.bold, diff --git a/lib/widgets/pharmacy/bottom_nav_pharmacy_home_item.dart b/lib/widgets/pharmacy/bottom_nav_pharmacy_home_item.dart index fba53c1c..24986c74 100644 --- a/lib/widgets/pharmacy/bottom_nav_pharmacy_home_item.dart +++ b/lib/widgets/pharmacy/bottom_nav_pharmacy_home_item.dart @@ -45,9 +45,9 @@ class BottomNavHomeItem extends StatelessWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: 15, - ), +// SizedBox( +// height: 15, +// ), currentIndex == index ? Divider( // color: Color(0xff5AB145), @@ -57,19 +57,24 @@ class BottomNavHomeItem extends StatelessWidget { thickness: 0, ), Container( + margin: EdgeInsets.only(bottom: 5.0), child: Image.asset( 'assets/images/habib-logo.png', ), height: 22.0, + ), SizedBox( - height: 9, + height: 5, ), - Texts( - title, - textAlign: TextAlign.start, - color: currentIndex == index ? Colors.grey : Colors.grey, - fontSize: 11, + Container( + margin: EdgeInsets.only(bottom: 7.0), + child: Texts( + title, + textAlign: TextAlign.start, + color: currentIndex == index ? Colors.grey : Colors.grey, + fontSize: 11, + ), ), // Added TextAlign Property ], diff --git a/lib/widgets/pharmacy/bottom_nav_pharmacy_item.dart b/lib/widgets/pharmacy/bottom_nav_pharmacy_item.dart index ff0cac32..6e6a5f53 100644 --- a/lib/widgets/pharmacy/bottom_nav_pharmacy_item.dart +++ b/lib/widgets/pharmacy/bottom_nav_pharmacy_item.dart @@ -39,7 +39,7 @@ class BottomNavPharmacyItem extends StatelessWidget { return Expanded( child: SizedBox( - // height: 72.0, + height: 66.0, child: Stack( clipBehavior: Clip.none, children: [ @@ -63,17 +63,18 @@ class BottomNavPharmacyItem extends StatelessWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: 15, - ), +// SizedBox( +// height: 15, +// ), currentIndex == index ? Divider( - color: Color(0xff5AB145), + color: Color(0xff5AB133), thickness: 3.5, ) : Divider( thickness: 0, ), + Container( child: Icon(currentIndex == index ? activeIcon : icon, color: isHome @@ -81,7 +82,7 @@ class BottomNavPharmacyItem extends StatelessWidget { : currentIndex == index ? Colors.grey : Colors.grey, - size: 22.0), + size: 20.0), ), SizedBox( height: 11, @@ -93,7 +94,7 @@ class BottomNavPharmacyItem extends StatelessWidget { textAlign: TextAlign.center, color: currentIndex == index ? Colors.grey : Colors.grey, fontWeight: currentIndex == index - ? FontWeight.bold + ? FontWeight.normal : FontWeight.w400, fontSize: currentIndex == index ? 13 : 11, ), @@ -108,13 +109,13 @@ class BottomNavPharmacyItem extends StatelessWidget { 0) Positioned( top: 11.5, - right: -4.5, + right: -3.5, child: Container( decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(15), ), - padding: EdgeInsets.only(left: 7, right: 6.5), + padding: EdgeInsets.only(left: 6.5, right: 6.5), height: 18, child: Center( child: Texts( diff --git a/lib/widgets/pharmacy/product_tile.dart b/lib/widgets/pharmacy/product_tile.dart index 78ea12b0..0d4c91e0 100644 --- a/lib/widgets/pharmacy/product_tile.dart +++ b/lib/widgets/pharmacy/product_tile.dart @@ -25,6 +25,7 @@ class productTile extends StatelessWidget { final PharmacyProduct product; final dynamic productID; final Function onDelete; + final dynamic approvedTotalReviews; // final VoidCallback deleteWishlistItems; productTile( @@ -43,6 +44,8 @@ class productTile extends StatelessWidget { this.product, this.productID, this.onDelete, + this.approvedTotalReviews, + }); @override @@ -112,22 +115,33 @@ class productTile extends StatelessWidget { ), ), this.isOrderDetails == false - ? Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RatingBar.readOnly( - initialRating: productRate, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, + ? Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.all(5), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( + initialRating: productRate, + size: 15.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), ), + Text( '$approvedTotalReviews', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.grey, + fontSize: 13), ), - ) + ], + ) : Container(), ], ), @@ -150,7 +164,9 @@ class productTile extends StatelessWidget { height: 50, ), IconButton( - icon: Icon(FontAwesomeIcons.shoppingCart, size: 15), + icon: Icon(Icons.shopping_cart, + size: 18, + color: Colors.blue,), onPressed: () async { GifLoaderDialogUtils.showMyDialog(context); await addToCartFunction(1, productID); From 1a6802ce24e1f6290850d32f8e48d8cebde50235 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Sun, 24 Oct 2021 16:31:52 +0300 Subject: [PATCH 10/60] Child Vaccine 3 --- lib/config/localized_values.dart | 2 +- .../all_habib_medical_service_page.dart | 3 +- .../ChildVaccines/add_newchild_page.dart | 445 ++++++++++-------- .../ChildVaccines/new/child_initial_page.dart | 149 ++++++ .../ChildVaccines/new/child_vaccine_page.dart | 2 +- lib/pages/landing/widgets/services_view.dart | 3 +- 6 files changed, 416 insertions(+), 188 deletions(-) create mode 100644 lib/pages/ChildVaccines/new/child_initial_page.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d9080ddb..7726b595 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1116,7 +1116,7 @@ const Map localizedValues = { "childName": {"en": "'CHILD NAME'", "ar": "إسم الطفل"}, "recordDeleted": {"en": "'Record Deleted'", "ar": "تم حذف السجل"}, "msg_email_address_up_to_date": { - "en": " Please ensure that the email address is up-to-date and proceed to view the schedule.", + "en": "Please ensure that the email address is up-to-date and proceed to view the schedule.", "ar": " يرجى التأكد من تحديث عنوان البريد الإلكتروني والمتابعة لعرض الجدول" }, "add-new-child": {"en": "ADD NEW CHILD", "ar": "إضافة طفل جديد"}, diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index 8f130d93..ffb974e1 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/parking_page.da import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/child_vaccines_page.dart'; +import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_initial_page.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_vaccine_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/findus/findus_page.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; @@ -278,7 +279,7 @@ class _AllHabibMedicalServiceState extends State { ServicesContainer( onTap: () => Navigator.push( context, - FadePage(page: ChildVaccinePage()), + FadePage(page: ChildInitialPage()), ), imageLocation: 'assets/images/new-design/children_vaccines_icon.png', title: TranslationBase.of(context).childVaccine, diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index edbd0745..496488d7 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/add_new_chil import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/DayCheckBoxDialog.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -27,15 +28,7 @@ class AddNewChildPage extends StatefulWidget { String dateAdd; List _scheduleList = List(); - List daysOfWeek = [ - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday, - DayOfWeek.Sunday - ]; + List daysOfWeek = [DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday]; DateTime startDay; DateTime endDay; @@ -43,13 +36,11 @@ class AddNewChildPage extends StatefulWidget { //AddNewChildPage({Key key, this.frequency, this.days, this.itemDescription}) : super(key: key); AddNewChildPage({Key key, this.frequency, this.days, this.itemDescription}) { startDay = DateTime.now(); - endDay = - DateTime.now(); //endDay = DateTime.now().add(Duration(days: days)); + endDay = DateTime.now(); //endDay = DateTime.now().add(Duration(days: days)); int hour = 24; //(24 / frequency).round(); int durations = 24 ~/ hour; for (int count = 0; count < durations; count++) { - _scheduleList.add(DateTime(DateTime.now().year, DateTime.now().month, - DateTime.now().day, (hour * count))); + _scheduleList.add(DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, (hour * count))); } } @@ -81,197 +72,210 @@ class _AddNewChildPageState extends State { @override Widget build(BuildContext context) { - var size = MediaQuery.of(context).size; return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).vaccination, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Column( - // crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 20, - ), - Texts( - TranslationBase.of(context).vaccinationAddChildMsg, - //+model.user.firstName, - textAlign: TextAlign.center, - ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).firstName, - controller: _firstTextController, - ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).middleName, - controller: _secondTextController, - ), - SizedBox( - height: 12, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).gender, - textAlign: TextAlign.end, - ), - ], - ), - Container( - width: double.infinity, - height: size.height * 0.12, + showNewAppBar: true, + body: Container( + child: Column( + children: [ + Expanded( + child: Padding( padding: EdgeInsets.all(12), - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.center, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ - Expanded( - child: Container( - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 1 ? Colors.white : Colors.black, - color: checkedValue == 1 ? Colors.red : Colors.white, - label: TranslationBase.of(context).male, - onTap: () { - setState(() { - checkedValue = 1; - print("checkedValue=" + checkedValue.toString()); - }); + Text( + TranslationBase.of(context).vaccinationAddChildMsg, + //+model.user.firstName, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + SizedBox( + height: 12, + ), + inputWidget(TranslationBase.of(context).firstName, "", _firstTextController), + SizedBox( + height: 12, + ), + inputWidget(TranslationBase.of(context).middleName, "", _secondTextController), - // bloodDetails. - }, - ), + SizedBox( + height: 12, + ), + Text( + TranslationBase.of(context).selectGender, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), ), - Expanded( - child: Container( - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 2 ? Colors.white : Colors.black, - color: checkedValue == 2 ? Colors.red : Colors.white, - label: TranslationBase.of(context).female, - // - onTap: () { + Row( + children: [ + Expanded( + child: Row( + children: [ + Radio( + value: checkedValue, + groupValue: 1, + onChanged: (v) { + setState(() { + checkedValue = 1; + }); + }), + Text( + TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + Expanded( + child: Row( + children: [ + Radio( + value: checkedValue, + groupValue: 2, + onChanged: (v) { + setState(() { + checkedValue = 2; + }); + }), + Text( + TranslationBase.of(context).female, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + ], + ), + + //========== + SizedBox( + height: 6, + ), + + InkWell( + onTap: () { + DatePicker.showDatePicker( + context, + showTitleActions: true, + // minTime: DateTime( + // DateTime.now().year, DateTime.now().month - 1, 1), + minTime: DateTime(1, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { setState(() { - checkedValue = 2; - print("checkedValue=" + checkedValue.toString()); + widget.startDay = date; }); - // bloodDetails.city=_selectedHospital.toString(); - - // bloodDetails. }, + currentTime: widget.startDay, + // locale: projectViewModel.localeType + ); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).dob, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + //getStartDay() + // DateUtil.yearMonthDay(DateTime.now()) + getStartDay(), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ], + ), + Icon( + Icons.calendar_today, + color: Color(0xff575757), + size: 18, + ) + ], ), ), - ) + ), + SizedBox( + height: 12, + ), + + //========= ], ), ), - //========== - SizedBox( - height: 6, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).dob, - textAlign: TextAlign.end, - ), - ], - ), - InkWell( - onTap: () { - DatePicker.showDatePicker( - context, - showTitleActions: true, - // minTime: DateTime( - // DateTime.now().year, DateTime.now().month - 1, 1), - minTime: DateTime(1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - setState(() { - widget.startDay = date; - }); - }, - currentTime: widget.startDay, - // locale: projectViewModel.localeType - ); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(//getStartDay() - // DateUtil.yearMonthDay(DateTime.now()) - getStartDay()), - Icon( - Icons.calendar_today, - color: Colors.black, - ) - ], - ), - ), - ), - SizedBox( - height: 12, - ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false - ? Colors.white24 - : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: TranslationBase.of(context).add, - // - onTap: () async { - newChild.babyName = _firstTextController.text + - " " + - _secondTextController.text; - newChild.gender = checkedValue.toString(); - newChild.strDOB = getStartDay(); - newChild.tempValue = true; - newChild.isLogin = true; + ), + Container( + width: double.infinity, + padding: EdgeInsets.all(16), + color: Colors.white, + child: SecondaryButton( + textColor: Colors.white, + color: checkedValue == false ? Colors.white24 : CustomColors.accentColor, + label: TranslationBase.of(context).add, + // + onTap: () async { + newChild.babyName = _firstTextController.text + " " + _secondTextController.text; + newChild.gender = checkedValue.toString(); + newChild.strDOB = getStartDay(); + newChild.tempValue = true; + newChild.isLogin = true; - await model.createNewBabyOrders(newChild: newChild); - if (model.isAdded) { - AppToast.showSuccessToast(message: TranslationBase.of(context).childAddedSuccessfully); - Navigator.pop(context, model.isAdded); - } else { - //TODO handling error - } - }, - ), + await model.createNewBabyOrders(newChild: newChild); + if (model.isAdded) { + AppToast.showSuccessToast(message: TranslationBase.of(context).childAddedSuccessfully); + Navigator.pop(context, model.isAdded); + } else { + //TODO handling error + } + }, ), - //========= - ], - ), + ), + ], ), ), // bottomSheet: @@ -313,4 +317,77 @@ class _AddNewChildPageState extends State { ), ); } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, + {VoidCallback suffixTap, bool isEnable = true, bool hasSelection = false, int lines, bool isInputTypeNum = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text, + controller: _controller, + maxLines: lines, + onChanged: (value) => {setState(() {})}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + suffixIconConstraints: BoxConstraints(minWidth: 50), + suffixIcon: suffixTap == null ? null : IconButton(icon: Icon(Icons.mic, color: Color(0xff2E303A)), onPressed: suffixTap), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } } diff --git a/lib/pages/ChildVaccines/new/child_initial_page.dart b/lib/pages/ChildVaccines/new/child_initial_page.dart new file mode 100644 index 00000000..6069f814 --- /dev/null +++ b/lib/pages/ChildVaccines/new/child_initial_page.dart @@ -0,0 +1,149 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; +import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'child_vaccine_page.dart'; + +class ChildInitialPage extends StatefulWidget { + @override + _ChildVaccinesPageState createState() => _ChildVaccinesPageState(); +} + +class _ChildVaccinesPageState extends State with SingleTickerProviderStateMixin { + TextEditingController titleController = TextEditingController(); + var checkedValue = false; + String addEmail = ""; + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getUserInformationRequestOrders(), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + isShowDecPage: true, + showNewAppBarTitle: true, + showNewAppBar: true, + description: TranslationBase.of(context).childVaccineInfo, + imagesInfo: [ + ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/child-vaccines/en/0.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/child-vaccines/ar/0.png'), + ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/child-vaccines/en/1.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/child-vaccines/ar/1.png') + ], + appBarTitle: TranslationBase.of(context).vaccination, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).welcomeBack, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + SizedBox( + height: 16, + ), + Text( + TranslationBase.of(context).msg_email_address_up_to_date, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + SizedBox( + height: 20, + ), + TextFields( + fillColor: Colors.red, + hintText: model.user != null ? model.user.emailAddress : "", + controller: titleController, + fontSize: 14, + hintColor: Colors.black, + fontWeight: FontWeight.w600, + suffixIcon: checkedValue ? Icons.check_box : Icons.check_box_outline_blank, + onSuffixTap: () { + setState(() { + checkedValue = !checkedValue; + }); + }, + onChanged: (text) { + addEmail = text; + model.user.emailAddress == addEmail ? checkedValue = false : checkedValue = true; + }, + validator: (value) { + if (value == null) { + return model.user.emailAddress; + } else { + return model.user.emailAddress; + } + }, + ), + ], + ), + ), + mFlex(1), + Container( + width: double.infinity, + color: Colors.white, + padding: EdgeInsets.all(16), + child: Column( + children: [ + if (checkedValue) + SecondaryButton( + textColor: Colors.white, + color: checkedValue == false ? Colors.white24 : CustomColors.green, + label: TranslationBase.of(context).updateEmail, + // + onTap: () { + model.user.emailAddress = addEmail.toString(); + AppToast.showSuccessToast(message: TranslationBase.of(context).updateEmailMsg); + // bloodDetails.city=_selectedHospital.toString(); + + // bloodDetails. + }, + ), + if (checkedValue) mHeight(16), + SecondaryButton( + textColor: Colors.white, + color: CustomColors.accentColor, + label: TranslationBase.of(context).viewListChildren, + // + onTap: () => Navigator.push( + context, + FadePage( + page: ChildVaccinePage(), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index 2a876cfa..71e1ea3f 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -56,7 +56,7 @@ class _ChildPageState extends State with SingleTickerProviderS ); }, child: Container( - margin: EdgeInsets.only(left: 16, right: 16), + margin: EdgeInsets.only(left: 16, right: 16,top: index==0?16:0,bottom: index==model.babyInformationModelList.length-1?16:0), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(12)), diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index 2eae79d3..37e7cd74 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -14,6 +14,7 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/parking_page.da import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/child_vaccines_page.dart'; +import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_initial_page.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_vaccine_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; @@ -103,7 +104,7 @@ class ServicesView extends StatelessWidget { } else if (index == 14) { Navigator.push( context, - FadePage(page: ChildVaccinePage()), + FadePage(page: ChildInitialPage()), ); } else if (index == 15) { Navigator.pop(context); From 1f077f71f8b037b5d88219089936c0b144bd35e5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 24 Oct 2021 17:10:57 +0300 Subject: [PATCH 11/60] no message --- lib/config/localized_values.dart | 2 + lib/core/service/client/base_app_client.dart | 4 +- .../SmartWatch/WeeklyHeartRateResModel.dart | 26 + .../SmartWatch/WeeklyStepsResModel.dart | 2 +- .../SmartWatch/YearlyHeartRateResModel.dart | 37 ++ .../Covid-DriveThru/Covid-TimeSlots.dart | 3 +- lib/pages/login/confirm-login.dart | 1 + .../distance/distanceTracker.dart | 569 +++++++++++++++++ .../health_data_list.dart | 92 +-- .../heartrate/heartrateTracker.dart | 570 ++++++++++++++++++ .../{Steps => steps}/stepsTracker.dart | 160 ++++- lib/uitl/translations_delegate_base.dart | 4 + lib/widgets/otp/sms-popup.dart | 2 +- 13 files changed, 1421 insertions(+), 51 deletions(-) create mode 100644 lib/models/SmartWatch/WeeklyHeartRateResModel.dart create mode 100644 lib/models/SmartWatch/YearlyHeartRateResModel.dart create mode 100644 lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart create mode 100644 lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart rename lib/pages/medical/smart_watch_health_data/{Steps => steps}/stepsTracker.dart (73%) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 26499051..2e444d4a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1581,5 +1581,7 @@ const Map localizedValues = { "syncHealthData": { "en": "Sync Health Data", "ar": "مزامنة البيانات الصحية" }, "steps": { "en": "Steps", "ar": "الخطوات" }, "avgSteps": { "en": "Average Steps", "ar": "متوسط الخطوات" }, + "avgDistance": { "en": "Average Distance", "ar": "متوسط المسافة" }, "enterDetails": {"en": "Enter Details", "ar": "أدخل التفاصيل"}, + "avgHeartRate": { "en": "Average Heart Rate", "ar": "متوسط معدل ضربات القلب" }, }; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index dc8f5288..b1a84fb0 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -115,7 +115,9 @@ class BaseAppClient { } // body['PatientID'] = 1018977; - body['TokenID'] = "@dm!n"; + // body['TokenID'] = "@dm!n"; + + body.removeWhere((key, value) => key == null || value == null); print("URL : $url"); final jsonBody = json.encode(body); diff --git a/lib/models/SmartWatch/WeeklyHeartRateResModel.dart b/lib/models/SmartWatch/WeeklyHeartRateResModel.dart new file mode 100644 index 00000000..17dbb563 --- /dev/null +++ b/lib/models/SmartWatch/WeeklyHeartRateResModel.dart @@ -0,0 +1,26 @@ +class WeeklyHeartRateResModel { + num valueAvg; + String machineDate; + int medCategoryID; + int patientID; + + WeeklyHeartRateResModel( + {this.valueAvg, this.machineDate, this.medCategoryID, this.patientID}); + + WeeklyHeartRateResModel.fromJson(Map json) { + num value = json['ValueAvg']; + valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; + machineDate = json['MachineDate']; + medCategoryID = json['MedCategoryID']; + patientID = json['PatientID']; + } + + Map toJson() { + final Map data = new Map(); + data['ValueAvg'] = this.valueAvg; + data['MachineDate'] = this.machineDate; + data['MedCategoryID'] = this.medCategoryID; + data['PatientID'] = this.patientID; + return data; + } +} diff --git a/lib/models/SmartWatch/WeeklyStepsResModel.dart b/lib/models/SmartWatch/WeeklyStepsResModel.dart index 9c1f2da5..ceae9d3b 100644 --- a/lib/models/SmartWatch/WeeklyStepsResModel.dart +++ b/lib/models/SmartWatch/WeeklyStepsResModel.dart @@ -17,7 +17,7 @@ class WeeklyStepsResModel { patientID = json['PatientID']; medCategoryID = json['MedCategoryID']; medSubCategoryID = json['MedSubCategoryID']; - value = num.tryParse(json['Value']).toInt(); + value = json['Value'] != null ? num.tryParse(json['Value']).toInt() : 0; machineDate = json['MachineDate']; patientOutSA = json['PatientOutSA']; notes = json['Notes']; diff --git a/lib/models/SmartWatch/YearlyHeartRateResModel.dart b/lib/models/SmartWatch/YearlyHeartRateResModel.dart new file mode 100644 index 00000000..1d045b19 --- /dev/null +++ b/lib/models/SmartWatch/YearlyHeartRateResModel.dart @@ -0,0 +1,37 @@ +class YearlyHeartRateResModel { + num valueAvg; + int medCategoryID; + int month; + String monthName; + int patientID; + int year; + + YearlyHeartRateResModel( + {this.valueAvg, + this.medCategoryID, + this.month, + this.monthName, + this.patientID, + this.year}); + + YearlyHeartRateResModel.fromJson(Map json) { + num value = json['ValueAvg']; + valueAvg = json['ValueAvg'] != null ? value.toInt() : 0; + medCategoryID = json['MedCategoryID']; + month = json['Month']; + monthName = json['MonthName']; + patientID = json['PatientID']; + year = json['Year']; + } + + Map toJson() { + final Map data = new Map(); + data['ValueAvg'] = this.valueAvg; + data['MedCategoryID'] = this.medCategoryID; + data['Month'] = this.month; + data['MonthName'] = this.monthName; + data['PatientID'] = this.patientID; + data['Year'] = this.year; + return data; + } +} diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index fb73280b..672dae53 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -23,7 +23,6 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -// import 'package:table_calendar/table_calendar.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; @@ -262,7 +261,7 @@ class _CovidTimeSlotsState extends State with TickerProviderStat final List meetings = []; _events.forEach((key, value) { final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); - final DateTime endTime = startTime.add(const Duration(hours: 2)); + final DateTime endTime = startTime.add(const Duration(minutes: 20)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); }); return meetings; diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 837e58ef..08df2e6c 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -621,6 +621,7 @@ class _ConfirmLogin extends State { GifLoaderDialogUtils.hideDialog(context), Future.delayed(Duration(seconds: 1), () { AppToast.showErrorToast(message: result); + startSMSService(tempType); }), } }) diff --git a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart new file mode 100644 index 00000000..32811cf9 --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart @@ -0,0 +1,569 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/WeeklyStepsResModel.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/YearlyStepsResModel.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class DistanceTracker extends StatefulWidget { + @override + _DistanceTrackerState createState() => _DistanceTrackerState(); +} + +class _DistanceTrackerState extends State with SingleTickerProviderStateMixin { + TabController _tabController; + + ProjectViewModel projectViewModel; + + num weeklyStatsAvgValue = 0; + num monthlyStatsAvgValue = 0; + num yearlyStatsAvgValue = 0; + + num avgWeeklyStepsValue = 0; + num avgMonthlyStepsValue = 0; + num avgYearlyStepsValue = 0; + + int weeklyDataLength = 0; + int monthlyDataLength = 0; + int yearlyDataLength = 0; + + List weekyStepsList = List(); + List monthlyStepsList = List(); + List yearlyStepsList = List(); + + List weeklyTimeSeriesData = []; + List monthlyTimeSeriesData = []; + List yearlyTimeSeriesData = []; + + bool isWeeklyDataLoaded = false; + bool isMonthlyDataLoaded = false; + bool isYearlyDataLoaded = false; + + @override + void initState() { + _tabController = new TabController(length: 3, vsync: this); + WidgetsBinding.instance.addPostFrameCallback((_) { + getWeeklyDistanceData(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).distance, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + body: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 0, bottom: 0, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Tab(text: TranslationBase.of(context).weekly), + Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).yearly), + ], + onTap: (value) { + print(value); + if (value == 0) { + getWeeklyDistanceData(); + } else if (value == 1) { + getMonthlyDistanceData(); + } else { + getYearlyDistanceData(); + } + }, + ), + Expanded( + child: new TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + isWeeklyDataLoaded ? getWeeklyDistanceDetails() : Container(), + isMonthlyDataLoaded ? getMonthlyDistanceDetails() : Container(), + isYearlyDataLoaded ? getYearlyDistanceDetails() : Container() + ], + controller: _tabController, + ), + ), + ], + ), + ); + } + + getWeeklyDistanceData() { + avgWeeklyStepsValue = 0; + weeklyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(7, 1, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + weekyStepsList.clear(); + res['Med_GetWeekStepsTransactionsStsList'].forEach((element) { + weekyStepsList.add(new WeeklyStepsResModel.fromJson(element)); + if (element['Value'] != null) { + num value = num.tryParse(element['Value'] ?? "0"); + avgWeeklyStepsValue += value; + weeklyDataLength++; + } + }); + generateWeekData(); + setState(() { + weeklyStatsAvgValue = avgWeeklyStepsValue ~/ weeklyDataLength; + weeklyStatsAvgValue = weeklyStatsAvgValue / 1000; + isWeeklyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getMonthlyDistanceData() { + avgMonthlyStepsValue = 0; + monthlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(7, 2, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + monthlyStepsList.clear(); + res['Med_GetMonthStepsTransactionsStsList'].forEach((element) { + monthlyStepsList.add(new WeeklyStepsResModel.fromJson(element)); + if (element['Value'] != null) { + num value = num.tryParse(element['Value'] ?? "0"); + avgMonthlyStepsValue += value; + monthlyDataLength++; + } + }); + generateMonthData(); + setState(() { + monthlyStatsAvgValue = avgMonthlyStepsValue ~/ monthlyDataLength; + monthlyStatsAvgValue = monthlyStatsAvgValue / 1000; + isMonthlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getYearlyDistanceData() { + avgYearlyStepsValue = 0; + yearlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(7, 3, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + yearlyStepsList.clear(); + res['Med_GetYearStepsTransactionsStsList'].forEach((element) { + yearlyStepsList.add(new YearlyStepsResModel.fromJson(element)); + if (element['ValueSum'] != null) { + num value = element['ValueSum']; + avgYearlyStepsValue += value; + yearlyDataLength++; + } + }); + generateYearData(); + setState(() { + yearlyStatsAvgValue = avgYearlyStepsValue ~/ yearlyDataLength; + yearlyStatsAvgValue = yearlyStatsAvgValue / 1000; + isYearlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + generateWeekData() { + if (weekyStepsList.length > 0) { + weeklyTimeSeriesData.clear(); + weekyStepsList.forEach( + (element) { + weeklyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.value != null ? (element.value.toDouble() / 1000) : 0.0, + ), + ); + }, + ); + } + } + + generateMonthData() { + if (monthlyStepsList.length > 0) { + monthlyTimeSeriesData.clear(); + monthlyStepsList.forEach( + (element) { + monthlyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.value != null ? element.value.toDouble() / 1000 : 0.0, + ), + ); + }, + ); + } + } + + generateYearData() { + if (yearlyStepsList.length > 0) { + yearlyTimeSeriesData.clear(); + yearlyStepsList.forEach( + (element) { + yearlyTimeSeriesData.add( + TimeSeriesSales2( + new DateTime(element.year, element.month, 1), + element.valueSum != null ? element.valueSum.toDouble() / 1000 : 0.0, + ), + ); + }, + ); + } + } + + getWeeklyDistanceDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: weeklyTimeSeriesData, + indexes: weeklyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgDistance, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(weeklyStatsAvgValue.toString() + " " + TranslationBase.of(context).km_, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + weekyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataWeekly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + getMonthlyDistanceDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: monthlyTimeSeriesData, + indexes: monthlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgDistance, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(monthlyStatsAvgValue.toString() + " " + TranslationBase.of(context).km_, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + monthlyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataMonthly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + getYearlyDistanceDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: yearlyTimeSeriesData, + indexes: yearlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgDistance, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).km_, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + yearlyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullData(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + List fullDataWeekly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).distance), + ], + ), + ); + weekyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue((step.value / 1000).toString() + " " + TranslationBase.of(context).km_, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + + List fullDataMonthly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).distance), + ], + ), + ); + monthlyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue((step.value / 1000).toString() + " " + TranslationBase.of(context).km_, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + + List fullData(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).distance), + ], + ), + ); + yearlyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + new DateTime(step.year, step.month, 1), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.valueSum != null ? (step.valueSum / 1000).toString() + " " + TranslationBase.of(context).km_ : "0.0 " + TranslationBase.of(context).km_ , isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + +} diff --git a/lib/pages/medical/smart_watch_health_data/health_data_list.dart b/lib/pages/medical/smart_watch_health_data/health_data_list.dart index 12dd7ee1..f63e3151 100644 --- a/lib/pages/medical/smart_watch_health_data/health_data_list.dart +++ b/lib/pages/medical/smart_watch_health_data/health_data_list.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/distance/distanceTracker.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -40,16 +42,26 @@ class _HealthDataListState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Heart Rate", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: HeartRateTracker(), + ), + ); + }, + child: Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text(TranslationBase.of(context).heart, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), ), Divider( color: Colors.grey[500], @@ -84,7 +96,7 @@ class _HealthDataListState extends State { ), Container( margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Steps", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text(TranslationBase.of(context).steps, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), ], ), @@ -92,34 +104,44 @@ class _HealthDataListState extends State { Divider( color: Colors.grey[500], ), - Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Distance", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - Divider( - color: Colors.grey[500], - ), - Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Energy", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: DistanceTracker(), + ), + ); + }, + child: Row( + children: [ + Container( + child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text(TranslationBase.of(context).distance, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), ), Divider( color: Colors.grey[500], ), + // Row( + // children: [ + // Container( + // child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), + // ), + // Container( + // margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + // child: Text("Energy", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + // ), + // ], + // ), + // Divider( + // color: Colors.grey[500], + // ), ], ), ), diff --git a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart new file mode 100644 index 00000000..d4fd738a --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart @@ -0,0 +1,570 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/WeeklyHeartRateResModel.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/YearlyHeartRateResModel.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class HeartRateTracker extends StatefulWidget { + @override + _HeartRateTrackerState createState() => _HeartRateTrackerState(); +} + +class _HeartRateTrackerState extends State with SingleTickerProviderStateMixin { + TabController _tabController; + + ProjectViewModel projectViewModel; + + num weeklyStatsAvgValue = 0; + num monthlyStatsAvgValue = 0; + num yearlyStatsAvgValue = 0; + + num avgWeeklyHearRateValue = 0; + num avgMonthlyHearRateValue = 0; + num avgYearlyHearRateValue = 0; + + int weeklyDataLength = 0; + int monthlyDataLength = 0; + int yearlyDataLength = 0; + + List weekyHearRateList = List(); + List monthlyHearRateList = List(); + List yearlyHearRateList = List(); + + List weeklyTimeSeriesData = []; + List monthlyTimeSeriesData = []; + List yearlyTimeSeriesData = []; + + bool isWeeklyDataLoaded = false; + bool isMonthlyDataLoaded = false; + bool isYearlyDataLoaded = false; + + @override + void initState() { + _tabController = new TabController(length: 3, vsync: this); + WidgetsBinding.instance.addPostFrameCallback((_) { + getWeeklyHeartRateData(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).heart, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + body: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 0, bottom: 0, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Tab(text: TranslationBase.of(context).weekly), + Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).yearly), + ], + onTap: (value) { + print(value); + if (value == 0) { + getWeeklyHeartRateData(); + } else if (value == 1) { + getMonthlyHeartRateData(); + } else { + // getYearlyHeartRateData(); + } + }, + ), + Expanded( + child: new TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + isWeeklyDataLoaded ? getWeeklyHeartRateDetails() : Container(), + isMonthlyDataLoaded ? getMonthlyHeartRateDetails() : Container(), + // isYearlyDataLoaded ? getYearlyDistanceDetails() : Container() + + // Container(), + // Container(), + Container() + ], + controller: _tabController, + ), + ), + ], + ), + ); + } + + getWeeklyHeartRateData() { + avgWeeklyHearRateValue = 0; + weeklyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(3, 1, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + weekyHearRateList.clear(); + res['Med_GetAvgWeekTransactionsStsList'].forEach((element) { + weekyHearRateList.add(new WeeklyHeartRateResModel.fromJson(element)); + if (element['ValueAvg'] != null) { + num value = element['ValueAvg']; + avgWeeklyHearRateValue += value.toInt(); + weeklyDataLength++; + } + }); + generateWeekData(); + setState(() { + weeklyStatsAvgValue = avgWeeklyHearRateValue ~/ weeklyDataLength; + isWeeklyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getMonthlyHeartRateData() { + avgMonthlyHearRateValue = 0; + monthlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(3, 2, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + monthlyHearRateList.clear(); + print(res['Med_GetAvgMonthTransactionsStsList'].length); + res['Med_GetAvgMonthTransactionsStsList'].forEach((element) { + monthlyHearRateList.add(new WeeklyHeartRateResModel.fromJson(element)); + if (element['ValueAvg'] != null) { + num value = element['ValueAvg']; + avgMonthlyHearRateValue += value.toInt(); + monthlyDataLength++; + } + }); + generateMonthData(); + setState(() { + monthlyStatsAvgValue = avgMonthlyHearRateValue ~/ monthlyDataLength; + isMonthlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getYearlyHeartRateData() { + avgYearlyHearRateValue = 0; + yearlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(7, 3, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + yearlyHearRateList.clear(); + res['Med_GetYearTransactionsStsList'].forEach((element) { + yearlyHearRateList.add(new YearlyHeartRateResModel.fromJson(element)); + if (element['ValueSum'] != null) { + num value = element['ValueSum']; + avgYearlyHearRateValue += value; + yearlyDataLength++; + } + }); + generateYearData(); + setState(() { + yearlyStatsAvgValue = avgYearlyHearRateValue ~/ yearlyDataLength; + isYearlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + generateWeekData() { + if (weekyHearRateList.length > 0) { + weeklyTimeSeriesData.clear(); + weekyHearRateList.forEach( + (element) { + weeklyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.valueAvg != null ? element.valueAvg.toDouble() : 0.0, + ), + ); + }, + ); + } + } + + generateMonthData() { + if (monthlyHearRateList.length > 0) { + monthlyTimeSeriesData.clear(); + monthlyHearRateList.forEach( + (element) { + monthlyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.valueAvg != null ? element.valueAvg.toDouble() : 0.0, + ), + ); + }, + ); + } + } + + generateYearData() { + if (yearlyHearRateList.length > 0) { + yearlyTimeSeriesData.clear(); + yearlyHearRateList.forEach( + (element) { + yearlyTimeSeriesData.add( + TimeSeriesSales2( + new DateTime(element.year, element.month, 1), + element.valueAvg != null ? element.valueAvg.toDouble() : 0.0, + ), + ); + }, + ); + } + } + + getWeeklyHeartRateDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: weeklyTimeSeriesData, + indexes: weeklyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(weeklyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + weekyHearRateList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataWeekly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + getMonthlyHeartRateDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: monthlyTimeSeriesData, + indexes: monthlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(monthlyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + monthlyHearRateList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataMonthly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + getYearlyHeartRateDetails() { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: yearlyTimeSeriesData, + indexes: yearlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgDistance, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).km_, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + yearlyHearRateList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullData(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + List fullDataWeekly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).heart), + ], + ), + ); + weekyHearRateList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + + List fullDataMonthly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).heart), + ], + ), + ); + monthlyHearRateList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } + + List fullData(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).distance), + ], + ), + ); + yearlyHearRateList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + new DateTime(step.year, step.month, 1), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } +} diff --git a/lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart similarity index 73% rename from lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart rename to lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart index f879886a..74ea76f4 100644 --- a/lib/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart @@ -28,15 +28,15 @@ class _StepsTrackerState extends State with SingleTickerProviderSt int yearlyStatsAvgValue = 0; int avgWeeklyStepsValue = 0; - int weeklyDataLength = 0; - int avgMonthlyStepsValue = 0; - int monthlyDataLength = 0; - int avgYearlyStepsValue = 0; + + int weeklyDataLength = 0; + int monthlyDataLength = 0; int yearlyDataLength = 0; List weekyStepsList = List(); + List monthlyStepsList = List(); List yearlyStepsList = List(); List weeklyTimeSeriesData = []; @@ -51,7 +51,6 @@ class _StepsTrackerState extends State with SingleTickerProviderSt void initState() { _tabController = new TabController(length: 3, vsync: this); WidgetsBinding.instance.addPostFrameCallback((_) { - // getYearlyStepsData(); getWeeklyStepsData(); }); super.initState(); @@ -97,6 +96,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt if (value == 0) { getWeeklyStepsData(); } else if (value == 1) { + getMonthlyStepsData(); } else { getYearlyStepsData(); } @@ -125,7 +125,6 @@ class _StepsTrackerState extends State with SingleTickerProviderSt GifLoaderDialogUtils.showMyDialog(context); service.getPatientHealthDataStats(6, 1, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res['Med_GetYearStepsTransactionsStsList']); weekyStepsList.clear(); res['Med_GetWeekStepsTransactionsStsList'].forEach((element) { weekyStepsList.add(new WeeklyStepsResModel.fromJson(element)); @@ -146,7 +145,32 @@ class _StepsTrackerState extends State with SingleTickerProviderSt }); } - getMonthlyStepsData() {} + getMonthlyStepsData() { + avgMonthlyStepsValue = 0; + monthlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(6, 2, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + monthlyStepsList.clear(); + res['Med_GetMonthStepsTransactionsStsList'].forEach((element) { + monthlyStepsList.add(new WeeklyStepsResModel.fromJson(element)); + if (element['Value'] != null) { + num value = num.tryParse(element['Value'] ?? "0"); + avgMonthlyStepsValue += value.toInt(); + monthlyDataLength++; + } + }); + generateMonthData(); + setState(() { + monthlyStatsAvgValue = avgMonthlyStepsValue ~/ monthlyDataLength; + isMonthlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } getYearlyStepsData() { avgYearlyStepsValue = 0; @@ -155,7 +179,6 @@ class _StepsTrackerState extends State with SingleTickerProviderSt GifLoaderDialogUtils.showMyDialog(context); service.getPatientHealthDataStats(6, 3, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res['Med_GetYearStepsTransactionsStsList']); yearlyStepsList.clear(); res['Med_GetYearStepsTransactionsStsList'].forEach((element) { yearlyStepsList.add(new YearlyStepsResModel.fromJson(element)); @@ -184,7 +207,23 @@ class _StepsTrackerState extends State with SingleTickerProviderSt weeklyTimeSeriesData.add( TimeSeriesSales2( DateUtil.convertStringToDate(element.machineDate), - element.value != null ? element.value : 0.0, + element.value != null ? element.value.toDouble() : 0.0, + ), + ); + }, + ); + } + } + + generateMonthData() { + if (monthlyStepsList.length > 0) { + monthlyTimeSeriesData.clear(); + monthlyStepsList.forEach( + (element) { + monthlyTimeSeriesData.add( + TimeSeriesSales2( + DateUtil.convertStringToDate(element.machineDate), + element.value != null ? element.value.toDouble() : 0.0, ), ); }, @@ -284,8 +323,77 @@ class _StepsTrackerState extends State with SingleTickerProviderSt } getMonthlyStepsDetails() { - return Container( - child: Text("Monthly"), + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: monthlyTimeSeriesData, + indexes: monthlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + ), + Container( + child: Container( + decoration: cardRadius(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), + child: Text(TranslationBase.of(context).avgSteps, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(monthlyStatsAvgValue.toString() + " " + TranslationBase.of(context).steps, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).details, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + monthlyStepsList.isEmpty + ? Container( + child: Center( + child: Text(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullDataMonthly(context), + ), + ], + ), + ) + ], + ), + ), + ], + ), ); } @@ -423,4 +531,34 @@ class _StepsTrackerState extends State with SingleTickerProviderSt ); return tableRow; } + + List fullDataMonthly(BuildContext context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).steps), + ], + ), + ); + monthlyStepsList.forEach( + (step) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + '${DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(step.machineDate), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.value.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index d72d0153..d61b4f10 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2526,6 +2526,10 @@ class TranslationBase { String get steps => localizedValues["steps"][locale.languageCode]; String get avgSteps => localizedValues["avgSteps"][locale.languageCode]; + + String get avgDistance => localizedValues["avgDistance"][locale.languageCode]; + + String get avgHeartRate => localizedValues["avgHeartRate"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/otp/sms-popup.dart index 12fb9d3e..600522f3 100644 --- a/lib/widgets/otp/sms-popup.dart +++ b/lib/widgets/otp/sms-popup.dart @@ -17,7 +17,7 @@ class SMSOTP { final Function onFailure; final context; - int remainingTime = 600; + int remainingTime = 120; Future timer; From d409875741f5b2469f773f35cf04f1edfd1a8600 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 25 Oct 2021 10:23:31 +0300 Subject: [PATCH 12/60] Smartwatch updates --- lib/config/config.dart | 4 +-- lib/core/service/client/base_app_client.dart | 2 +- .../distance/distanceTracker.dart | 2 ++ .../heartrate/heartrateTracker.dart | 20 +++++++------- .../smart_watch_instructions.dart | 2 +- .../steps/stepsTracker.dart | 2 ++ lib/uitl/date_uitl.dart | 9 +++++++ lib/widgets/charts/show_chart.dart | 27 +++++++++++-------- 8 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index efac58e5..7270f91e 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index b1a84fb0..4f8a3f5d 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -115,7 +115,7 @@ class BaseAppClient { } // body['PatientID'] = 1018977; - // body['TokenID'] = "@dm!n"; + body['TokenID'] = "@dm!n"; body.removeWhere((key, value) => key == null || value == null); diff --git a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart index 32811cf9..787bc210 100644 --- a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart @@ -262,6 +262,7 @@ class _DistanceTrackerState extends State with SingleTickerProv timeSeries: weeklyTimeSeriesData, indexes: weeklyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( @@ -337,6 +338,7 @@ class _DistanceTrackerState extends State with SingleTickerProv timeSeries: monthlyTimeSeriesData, indexes: monthlyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( diff --git a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart index d4fd738a..1c109669 100644 --- a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart @@ -99,7 +99,7 @@ class _HeartRateTrackerState extends State with SingleTickerPr } else if (value == 1) { getMonthlyHeartRateData(); } else { - // getYearlyHeartRateData(); + getYearlyHeartRateData(); } }, ), @@ -109,11 +109,7 @@ class _HeartRateTrackerState extends State with SingleTickerPr children: [ isWeeklyDataLoaded ? getWeeklyHeartRateDetails() : Container(), isMonthlyDataLoaded ? getMonthlyHeartRateDetails() : Container(), - // isYearlyDataLoaded ? getYearlyDistanceDetails() : Container() - - // Container(), - // Container(), - Container() + isYearlyDataLoaded ? getYearlyHeartRateDetails() : Container() ], controller: _tabController, ), @@ -183,13 +179,13 @@ class _HeartRateTrackerState extends State with SingleTickerPr yearlyDataLength = 0; DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); - service.getPatientHealthDataStats(7, 3, context).then((res) { + service.getPatientHealthDataStats(3, 3, context).then((res) { GifLoaderDialogUtils.hideDialog(context); yearlyHearRateList.clear(); res['Med_GetYearTransactionsStsList'].forEach((element) { yearlyHearRateList.add(new YearlyHeartRateResModel.fromJson(element)); - if (element['ValueSum'] != null) { - num value = element['ValueSum']; + if (element['ValueAvg'] != null) { + num value = element['ValueAvg']; avgYearlyHearRateValue += value; yearlyDataLength++; } @@ -264,6 +260,7 @@ class _HeartRateTrackerState extends State with SingleTickerPr timeSeries: weeklyTimeSeriesData, indexes: weeklyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( @@ -339,6 +336,7 @@ class _HeartRateTrackerState extends State with SingleTickerPr timeSeries: monthlyTimeSeriesData, indexes: monthlyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( @@ -424,11 +422,11 @@ class _HeartRateTrackerState extends State with SingleTickerPr children: [ Container( padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0), - child: Text(TranslationBase.of(context).avgDistance, style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)), ), Container( margin: EdgeInsets.only(bottom: 10.0), - child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).km_, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), ], ), diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index c550fa08..b4471611 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -447,7 +447,7 @@ class _SmartWatchInstructionsState extends State { options: CarouselOptions( // enableInfiniteScroll: true, viewportFraction: 0.99, - height: MediaQuery.of(context).size.height*1.02 ), + height: MediaQuery.of(context).size.height*1.1 ), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { diff --git a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart index 74ea76f4..c1be5f2d 100644 --- a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart @@ -258,6 +258,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt timeSeries: weeklyTimeSeriesData, indexes: weeklyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( @@ -333,6 +334,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt timeSeries: monthlyTimeSeriesData, indexes: monthlyTimeSeriesData.length ~/ 5.5, horizontalInterval: 8, + isWeeklyOrMonthly: true, ), ), Container( diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index 337d4af0..a11b85e6 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -395,6 +395,15 @@ class DateUtil { return ""; } + /// get data formatted like 26/4/2020 + /// [dateTime] convert DateTime to data formatted + static String getDayMonthDateFormatted(DateTime dateTime) { + if (dateTime != null) + return DateFormat('dd/MM').format(dateTime); + else + return ""; + } + /// get data formatted like 26/4/2020 /// [dateTime] convert DateTime to data formatted according to language static String getDayMonthYearDateFormattedLang(DateTime dateTime, bool isArabic) { diff --git a/lib/widgets/charts/show_chart.dart b/lib/widgets/charts/show_chart.dart index 86c83f5b..301d45ff 100644 --- a/lib/widgets/charts/show_chart.dart +++ b/lib/widgets/charts/show_chart.dart @@ -10,8 +10,9 @@ class ShowChart extends StatelessWidget { final List timeSeries; final int indexes; final double horizontalInterval; + final bool isWeeklyOrMonthly; - ShowChart({this.title, this.timeSeries, this.indexes, this.horizontalInterval = 8.0}); + ShowChart({this.title, this.timeSeries, this.indexes, this.horizontalInterval = 8.0, this.isWeeklyOrMonthly = false}); List xAxixs = List(); List yAxixs = List(); @@ -115,19 +116,23 @@ class ShowChart extends StatelessWidget { rotateAngle: -65, margin: 22, getTitles: (value) { - if (timeSeries.length < 15) { - if (timeSeries.length > value.toInt()) { - return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; - } else - return ''; + if(isWeeklyOrMonthly) { + return '${timeSeries[value.toInt()].time.day}/ ${timeSeries[value.toInt()].time.month}'; } else { - if (value.toInt() == 0) return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; - if (value.toInt() == timeSeries.length - 1) return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; - if (xAxixs.contains(value.toInt())) { - return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + if (timeSeries.length < 15) { + if (timeSeries.length > value.toInt()) { + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + } else + return ''; + } else { + if (value.toInt() == 0) return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + if (value.toInt() == timeSeries.length - 1) return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + if (xAxixs.contains(value.toInt())) { + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + } } + return ''; } - return ''; }, ), leftTitles: SideTitles( From aad071ac6702607666c8576f09a0dc01dee95e5a Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 25 Oct 2021 15:14:36 +0300 Subject: [PATCH 13/60] Packages and Offers apply token --- .../opentok/LocalVideo.kt | 58 ++++++ .../diplomaticquarterapp/opentok/OpenTok.kt | 48 +++-- .../opentok/{Video.kt => RemoteVideo.kt} | 29 ++- .../utils/OpenTokPlatformBridge.kt | 10 +- ios/Flutter/.last_build_id | 2 +- ios/Runner.xcodeproj/project.pbxproj | 8 + ios/Runner/OpenTok/OpenTok.swift | 130 ++----------- .../OpenTok/OpenTokLocalVideoFactory.swift | 91 +++++++++ .../OpenTok/OpenTokRemoteVideoFactory.swift | 91 +++++++++ lib/config/config.dart | 4 +- lib/config/localized_values.dart | 4 + .../requests/CreateCustomerRequestModel.dart | 35 +++- lib/core/service/client/base_app_client.dart | 64 ++++++- .../PackagesOffersServices.dart | 75 ++++++-- .../PackagesOffersViewModel.dart | 2 + lib/main.dart | 1 + .../fragments/home_page_fragment2.dart | 4 +- .../CreateCustomerDailogPage.dart | 12 +- .../packages_offers/OfferAndPackagesPage.dart | 50 ++++- lib/pages/webRTC/OpenTok/OpenTok.dart | 180 ++++++++++++++++++ .../webRTC/OpenTok/OpenTokPlatformBridge.dart | 86 +++++++++ lib/routes.dart | 8 +- lib/uitl/translations_delegate_base.dart | 1 + .../offers_packages/PackagesCartItemCard.dart | 2 +- 24 files changed, 783 insertions(+), 212 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/{Video.kt => RemoteVideo.kt} (53%) create mode 100644 ios/Runner/OpenTok/OpenTokLocalVideoFactory.swift create mode 100644 ios/Runner/OpenTok/OpenTokRemoteVideoFactory.swift create mode 100644 lib/pages/webRTC/OpenTok/OpenTok.dart create mode 100644 lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt new file mode 100644 index 00000000..cfebfe65 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt @@ -0,0 +1,58 @@ +package com.ejada.hmg.opentok + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.ejada.hmg.R +import io.flutter.plugin.common.StandardMessageCodec +import io.flutter.plugin.platform.PlatformView +import io.flutter.plugin.platform.PlatformViewFactory + +class LocalVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { + + companion object { + private lateinit var view: LocalVideoPlatformView + + fun getViewInstance(context: Context): LocalVideoPlatformView { + if(!this::view.isInitialized) { + view = LocalVideoPlatformView(context) + } + + return view + } + } + + override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + return getViewInstance(context) + } +} + +class LocalVideoPlatformView(context: Context) : PlatformView { + private val videoContainer: LocalVideoContainer = LocalVideoContainer(context) + + val container get() = videoContainer.publisherContainer + + override fun getView(): View { + return videoContainer + } + + override fun dispose() {} +} + +class LocalVideoContainer @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, + defStyleRes: Int = 0 +) : LinearLayout(context, attrs, defStyle, defStyleRes) { + + var publisherContainer: FrameLayout private set + + init { + val view = LayoutInflater.from(context).inflate(R.layout.local_video, this, true) + publisherContainer = view.findViewById(R.id.publisher_container) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt index 5606343f..0cdc3751 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt @@ -1,25 +1,17 @@ -package com.example.basic_video_chat_flutter +package com.ejada.hmg.opentok import android.content.Context import android.os.Handler import android.os.Looper -import android.util.AttributeSet import android.util.Log -import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.FrameLayout -import android.widget.LinearLayout import com.opentok.android.* import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.StandardMessageCodec -import io.flutter.plugin.platform.PlatformView -import io.flutter.plugin.platform.PlatformViewFactory -enum class SdkState { +enum class OpenTokSDKState { LOGGED_OUT, LOGGED_IN, WAIT, @@ -27,15 +19,21 @@ enum class SdkState { } class OpenTok(private var context: Context, private var flutterEngine: FlutterEngine){ - private lateinit var opentokVideoPlatformView: OpentokVideoPlatformView + private lateinit var remoteVideoPlatformView: RemoteVideoPlatformView + private lateinit var localVideoPlatformView: LocalVideoPlatformView init { - opentokVideoPlatformView = OpentokVideoFactory.getViewInstance(context) + remoteVideoPlatformView = RemoteVideoFactory.getViewInstance(context) flutterEngine .platformViewsController .registry - // opentok-video-container is a custom platform-view-type - .registerViewFactory("opentok-video-container", OpentokVideoFactory()) + .registerViewFactory("remote-video-container", RemoteVideoFactory()) + + localVideoPlatformView = LocalVideoFactory.getViewInstance(context) + flutterEngine + .platformViewsController + .registry + .registerViewFactory("local-video-container", LocalVideoFactory()) } private var session: Session? = null @@ -54,15 +52,15 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn renderer?.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) - opentokVideoPlatformView.publisherContainer.addView(view) + localVideoPlatformView.container.addView(view) } - notifyFlutter(SdkState.LOGGED_IN) + notifyFlutter(OpenTokSDKState.LOGGED_IN) session.publish(publisher) } override fun onDisconnected(session: Session) { - notifyFlutter(SdkState.LOGGED_OUT) + notifyFlutter(OpenTokSDKState.LOGGED_OUT) } override fun onStreamReceived(session: Session, stream: Stream) { @@ -76,7 +74,7 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn setSubscriberListener(subscriberListener) session.subscribe(this) - opentokVideoPlatformView.subscriberContainer.addView(view) + remoteVideoPlatformView.container.addView(view) } } } @@ -90,13 +88,13 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn if (subscriber != null) { subscriber = null - opentokVideoPlatformView.subscriberContainer.removeAllViews() + remoteVideoPlatformView.container.removeAllViews() } } override fun onError(session: Session, opentokError: OpentokError) { Log.d("MainActivity", "Session error: " + opentokError.message) - notifyFlutter(SdkState.ERROR) + notifyFlutter(OpenTokSDKState.ERROR) } } @@ -111,7 +109,7 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn override fun onError(publisherKit: PublisherKit, opentokError: OpentokError) { Log.d("MainActivity", "PublisherKit onError: " + opentokError.message) - notifyFlutter(SdkState.ERROR) + notifyFlutter(OpenTokSDKState.ERROR) } } @@ -122,12 +120,12 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn override fun onDisconnected(subscriberKit: SubscriberKit) { Log.d("MainActivity", "onDisconnected: Subscriber disconnected. Stream: " + subscriberKit.stream.streamId) - notifyFlutter(SdkState.LOGGED_OUT) + notifyFlutter(OpenTokSDKState.LOGGED_OUT) } override fun onError(subscriberKit: SubscriberKit, opentokError: OpentokError) { Log.d("MainActivity", "SubscriberKit onError: " + opentokError.message) - notifyFlutter(SdkState.ERROR) + notifyFlutter(OpenTokSDKState.ERROR) } } @@ -137,7 +135,7 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn val sessionId = requireNotNull(call.argument("sessionId")) val token = requireNotNull(call.argument("token")) - notifyFlutter(SdkState.WAIT) + notifyFlutter(OpenTokSDKState.WAIT) session = Session.Builder(context, apiKey, sessionId).build() session?.setSessionListener(sessionListener) session?.connect(token) @@ -161,7 +159,7 @@ class OpenTok(private var context: Context, private var flutterEngine: FlutterEn result.success("") } - private fun notifyFlutter(state: SdkState) { + private fun notifyFlutter(state: OpenTokSDKState) { Handler(Looper.getMainLooper()).post { MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "OpenTok-Platform-Bridge") .invokeMethod("updateState", state.toString()) diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt similarity index 53% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt index 0153908a..9116a1e8 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/Video.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt @@ -1,4 +1,4 @@ -package com.example.basic_video_chat_flutter +package com.ejada.hmg.opentok import android.content.Context import android.util.AttributeSet @@ -6,18 +6,19 @@ import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout import android.widget.LinearLayout +import com.ejada.hmg.R import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -class OpentokVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { +class RemoteVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { companion object { - private lateinit var view: OpentokVideoPlatformView + private lateinit var view: RemoteVideoPlatformView - fun getViewInstance(context: Context): OpentokVideoPlatformView { + fun getViewInstance(context: Context): RemoteVideoPlatformView { if(!this::view.isInitialized) { - view = OpentokVideoPlatformView(context) + view = RemoteVideoPlatformView(context) } return view @@ -29,11 +30,10 @@ class OpentokVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { } } -class OpentokVideoPlatformView(context: Context) : PlatformView { - private val videoContainer: OpenTokVideoContainer = OpenTokVideoContainer(context) +class RemoteVideoPlatformView(context: Context) : PlatformView { + private val videoContainer: RemoteVideoContainer = RemoteVideoContainer(context) - val subscriberContainer get() = videoContainer.subscriberContainer - val publisherContainer get() = videoContainer.publisherContainer + val container get() = videoContainer.subscriberContainer override fun getView(): View { return videoContainer @@ -42,22 +42,17 @@ class OpentokVideoPlatformView(context: Context) : PlatformView { override fun dispose() {} } -class OpenTokVideoContainer @JvmOverloads constructor( +class RemoteVideoContainer @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0, defStyleRes: Int = 0 ) : LinearLayout(context, attrs, defStyle, defStyleRes) { - var subscriberContainer: FrameLayout - private set - - var publisherContainer: FrameLayout - private set + var subscriberContainer: FrameLayout private set init { - val view = LayoutInflater.from(context).inflate(R.layout.view_video, this, true) + val view = LayoutInflater.from(context).inflate(R.layout.remote_video, this, true) subscriberContainer = view.findViewById(R.id.subscriber_container) - publisherContainer = view.findViewById(R.id.publisher_container) } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt index 29ded185..6ac62546 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt @@ -1,16 +1,8 @@ package com.ejada.hmg.utils -import android.content.Context -import android.net.wifi.WifiManager -import android.util.Log import com.ejada.hmg.MainActivity -import com.ejada.hmg.hmgwifi.HMG_Guest -import com.ejada.hmg.hmgwifi.HMG_Internet -import com.ejada.hmg.geofence.GeoZoneModel -import com.ejada.hmg.geofence.HMG_Geofence -import com.example.basic_video_chat_flutter.OpenTok +import com.ejada.hmg.opentok.OpenTok import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 3aa2cd1e..53427e0c 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -3f3d14a0ae775b56806906c2cb14a1f0 \ No newline at end of file +3f8c659591fcdd0e47e3895f74af395c \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9505487e..6c02c983 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; }; + 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; }; 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; @@ -52,6 +54,8 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = ""; }; + 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = ""; }; 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; }; 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; }; 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; @@ -107,6 +111,8 @@ isa = PBXGroup; children = ( 306FE6CA271D8B73002D6EFC /* OpenTok.swift */, + 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */, + 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */, ); path = OpenTok; sourceTree = ""; @@ -396,11 +402,13 @@ E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */, E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */, E91B539B256AAA6500E96549 /* HMG_Internet.swift in Sources */, E91B5397256AAA6500E96549 /* Extensions.swift in Sources */, diff --git a/ios/Runner/OpenTok/OpenTok.swift b/ios/Runner/OpenTok/OpenTok.swift index 3cb7fdbe..9cc0b79a 100644 --- a/ios/Runner/OpenTok/OpenTok.swift +++ b/ios/Runner/OpenTok/OpenTok.swift @@ -7,6 +7,7 @@ import Foundation import OpenTok +import UIKit enum SdkState: String { case loggedOut = "LOGGED_OUT" @@ -18,16 +19,21 @@ enum SdkState: String { class OpenTok : NSObject{ private var mainViewController:MainFlutterVC! private var registrar:FlutterPluginRegistrar? + var methodChannel: FlutterMethodChannel? + init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){ self.mainViewController = mainViewController + self.methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger) self.registrar = registrar - - let factory = OpentokVideoFactory(messenger: registrar!.messenger()) - registrar?.register(factory, withId: "opentok-video-container") + + let remoteVDOFactory = OpenTokRemoteVideoFactory(messenger: registrar!.messenger()) + registrar?.register(remoteVDOFactory, withId: "remote-video-container") + + let localVDOFactory = OpenTokLocalVideoFactory(messenger: registrar!.messenger()) + registrar?.register(localVDOFactory, withId: "local-video-container") } var otSession: OTSession? - var vonageChannel: FlutterMethodChannel? var subscriber: OTSubscriber? lazy var publisher: OTPublisher = { @@ -86,7 +92,7 @@ class OpenTok : NSObject{ func notifyFlutter(state: SdkState) { - vonageChannel?.invokeMethod("updateState", arguments: state.rawValue) + methodChannel?.invokeMethod("updateState", arguments: state.rawValue) } } @@ -106,10 +112,10 @@ extension OpenTok: OTSessionDelegate { if let pubView = self.publisher.view { pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300) - if OpentokVideoFactory.view == nil { - OpentokVideoFactory.viewToAddPub = pubView + if OpenTokLocalVideoFactory.view == nil { + OpenTokLocalVideoFactory.viewToAddPub = pubView } else { - OpentokVideoFactory.view?.addPublisherView(pubView) + OpenTokLocalVideoFactory.view?.addPublisherView(pubView) } } } @@ -156,12 +162,12 @@ extension OpenTok: OTSubscriberDelegate { print("Subscriber connected") if let subView = self.subscriber?.view { - subView.frame = CGRect(x: 0, y: 0, width: 200, height: 300) + subView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) - if OpentokVideoFactory.view == nil { - OpentokVideoFactory.viewToAddSub = subView + if OpenTokRemoteVideoFactory.view == nil { + OpenTokRemoteVideoFactory.viewToAddSub = subView } else { - OpentokVideoFactory.view?.addSubscriberView(subView) + OpenTokRemoteVideoFactory.view?.addSubscriberView(subView) } } } @@ -171,103 +177,3 @@ extension OpenTok: OTSubscriberDelegate { } } - -class OpentokVideoFactory: NSObject, FlutterPlatformViewFactory { - static var view: OpentokVideoPlatformView? - - static var viewToAddSub: UIView? - static var viewToAddPub: UIView? - - static func getViewInstance( - frame: CGRect, - viewId: Int64, - args: Any?, - messenger: FlutterBinaryMessenger? - ) -> OpentokVideoPlatformView{ - if(view == nil) { - view = OpentokVideoPlatformView() - if viewToAddSub != nil { - view?.addSubscriberView(viewToAddSub!) - } - if viewToAddPub != nil { - view?.addPublisherView(viewToAddPub!) - } - } - - return view! - } - - private var messenger: FlutterBinaryMessenger - - init(messenger: FlutterBinaryMessenger) { - self.messenger = messenger - super.init() - } - - func create( - withFrame frame: CGRect, - viewIdentifier viewId: Int64, - arguments args: Any? - ) -> FlutterPlatformView { - return OpentokVideoFactory.getViewInstance( - frame: frame, - viewId: viewId, - args: args, - messenger: messenger) - } -} - -class OpentokVideoPlatformView: NSObject, FlutterPlatformView { - private let videoContainer: OpenTokVideoContainer - - override init() { - videoContainer = OpenTokVideoContainer() - super.init() - } - - public func addSubscriberView(_ view: UIView) { - videoContainer.addSubscriberView(view) - } - - public func addPublisherView(_ view: UIView) { - videoContainer.addPublisherView(view) - } - - func view() -> UIView { - return videoContainer - } -} - -final class OpenTokVideoContainer: UIView { - private let subscriberContainer = UIView() - private let publisherContainer = UIView() - - init() { - super.init(frame: .zero) - addSubview(subscriberContainer) - addSubview(publisherContainer) - } - - - public func addSubscriberView(_ view: UIView) { - subscriberContainer.addSubview(view) - } - - public func addPublisherView(_ view: UIView) { - publisherContainer.addSubview(view) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func layoutSubviews() { - super.layoutSubviews() - let width = frame.width - let height = frame.height - - let videoWidth = width / 2 - subscriberContainer.frame = CGRect(x: 0, y: 0, width: videoWidth, height: height) - publisherContainer.frame = CGRect(x: videoWidth, y: 0, width: videoWidth, height: height) - } -} diff --git a/ios/Runner/OpenTok/OpenTokLocalVideoFactory.swift b/ios/Runner/OpenTok/OpenTokLocalVideoFactory.swift new file mode 100644 index 00000000..361b482d --- /dev/null +++ b/ios/Runner/OpenTok/OpenTokLocalVideoFactory.swift @@ -0,0 +1,91 @@ +// +// OpenTokLocalVideoFactory.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 20/10/2021. +// + +import Foundation + +class OpenTokLocalVideoFactory: NSObject, FlutterPlatformViewFactory { + static var view: LocalVideoPlatformView? + + static var viewToAddPub: UIView? + + static func getViewInstance( + frame: CGRect, + viewId: Int64, + args: Any?, + messenger: FlutterBinaryMessenger? + ) -> LocalVideoPlatformView{ + if(view == nil) { + view = LocalVideoPlatformView() + if viewToAddPub != nil { + view?.addPublisherView(viewToAddPub!) + } + } + + return view! + } + + private var messenger: FlutterBinaryMessenger + + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return OpenTokLocalVideoFactory.getViewInstance( + frame: frame, + viewId: viewId, + args: args, + messenger: messenger) + } +} + +class LocalVideoPlatformView: NSObject, FlutterPlatformView { + private let videoContainer: LocalVideoContainer + + override init() { + videoContainer = LocalVideoContainer() + super.init() + } + + public func addPublisherView(_ view: UIView) { + videoContainer.addPublisherView(view) + } + + func view() -> UIView { + return videoContainer + } +} + +final class LocalVideoContainer: UIView { + private let publisherContainer = UIView() + + init() { + super.init(frame: .zero) + addSubview(publisherContainer) + } + + public func addPublisherView(_ view: UIView) { + publisherContainer.addSubview(view) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + let width = frame.width + let height = frame.height + + publisherContainer.frame = CGRect(x: 0, y: 0, width: width, height: height) + } +} diff --git a/ios/Runner/OpenTok/OpenTokRemoteVideoFactory.swift b/ios/Runner/OpenTok/OpenTokRemoteVideoFactory.swift new file mode 100644 index 00000000..50dcf695 --- /dev/null +++ b/ios/Runner/OpenTok/OpenTokRemoteVideoFactory.swift @@ -0,0 +1,91 @@ +// +// OpenTokRemoteVideoFactory.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 20/10/2021. +// + +import Foundation + +class OpenTokRemoteVideoFactory: NSObject, FlutterPlatformViewFactory { + static var view: RemoteVideoPlatformView? + + static var viewToAddSub: UIView? + + static func getViewInstance( + frame: CGRect, + viewId: Int64, + args: Any?, + messenger: FlutterBinaryMessenger? + ) -> RemoteVideoPlatformView{ + if(view == nil) { + view = RemoteVideoPlatformView() + if viewToAddSub != nil { + view?.addSubscriberView(viewToAddSub!) + } + } + + return view! + } + + private var messenger: FlutterBinaryMessenger + + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return OpenTokRemoteVideoFactory.getViewInstance( + frame: frame, + viewId: viewId, + args: args, + messenger: messenger) + } +} + +class RemoteVideoPlatformView: NSObject, FlutterPlatformView { + private let videoContainer: RemoteVideoContainer + + override init() { + videoContainer = RemoteVideoContainer() + super.init() + } + + public func addSubscriberView(_ view: UIView) { + videoContainer.addSubscriberView(view) + } + + func view() -> UIView { + return videoContainer + } +} + +final class RemoteVideoContainer: UIView { + private let subscriberContainer = UIView() + + init() { + super.init(frame: .zero) + addSubview(subscriberContainer) + } + + + public func addSubscriberView(_ view: UIView) { + subscriberContainer.addSubview(view) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + let width = frame.width + let height = frame.height + subscriberContainer.frame = CGRect(x: 0, y: 0, width: width, height: height) + } +} diff --git a/lib/config/config.dart b/lib/config/config.dart index acb8d80a..c1622769 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -6,8 +6,10 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; const MAX_SMALL_SCREEN = 660; // PACKAGES and OFFERS -const EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; +const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/offersdiscounts'; +// const EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; const PACKAGES_CATEGORIES = '/api/categories'; +const PACKAGES_TOKEN = '/api/token'; const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index c7a60f96..3bf6e2b2 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -822,6 +822,10 @@ const Map localizedValues = { }, "failedToAccessHmgServices": {"en": "Connected with HMG Network,\n\nBut failed to access HMG services", "ar": "Connected with HMG Network,\n\nBut failed to access HMG services"}, "offerAndPackages": {"en": "Offers and Packages", "ar": "العروض والباقات"}, + "offerAndPackagesDetails": { + "en": "This service allows you to view all HMG Offers:", + "ar": "This service allows you to view all HMG Offers:" + }, "InvoiceNo": {"en": "Invoice No", "ar": "رقم الفاتورة"}, "InvoiceDate": {"en": "Invoice Date", "ar": "تاريخ الفاتورة"}, "SpecialResult": {"en": " Special Result", "ar": "نتيجة خاصة"}, diff --git a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart index 116545bd..9cc3d3b9 100644 --- a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart +++ b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart @@ -1,20 +1,41 @@ +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:flutter/cupertino.dart'; class PackagesCustomerRequestModel { + String username; + String first_name; + String last_name; String email; - String phoneNumber; + String phone; + String national_id; + String date_of_birth; - PackagesCustomerRequestModel({@required this.email, @required this.phoneNumber}); + + PackagesCustomerRequestModel.fromUser(AuthenticatedUser user){ + this.username = "${user.patientID}"; + this.first_name = user.firstName; + this.last_name = user.lastName; + this.email = user.emailAddress; + this.phone = user.mobileNumber; + this.national_id = user.patientIdentificationNo; + this.date_of_birth = user.dateofBirth; + } Map json() { return { "customer" : { - "email": email, - "addresses": [{ - "email": email, - "phone_number": phoneNumber - }] + "email": email ?? '', + "username": username ?? '', + "national_id": national_id ?? '', + "phone": phone ?? '', + "date_of_birth": date_of_birth ?? '', + "first_name": first_name ?? '', + "last_name": last_name ?? '', + // "addresses": [{ + // "email": email, + // "phone_number": phoneNumber + // }] } }; } diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index ac96e35e..6ec6e8af 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -1,9 +1,11 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io' show Platform; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; +import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; @@ -468,7 +470,7 @@ class BaseAppClient { simplePost( String fullUrl, { - Map body, + Map body, Map headers, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, }) async { @@ -476,14 +478,17 @@ class BaseAppClient { print("URL Query String: $url"); if (await Utils.checkConnection()) { + headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.post( url.trim(), body: json.encode(body), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + headers: headers, ); final int statusCode = response.statusCode; print("statusCode :$statusCode"); + if(await handleUnauthorized(statusCode, forUrl: fullUrl)) + simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -495,7 +500,7 @@ class BaseAppClient { } } - simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams}) async { + simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { String url = fullUrl; print("URL Query String: $url"); @@ -507,13 +512,16 @@ class BaseAppClient { } if (await Utils.checkConnection()) { + headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.get( url.trim(), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + headers: headers, ); final int statusCode = response.statusCode; print("statusCode :$statusCode"); + if(await handleUnauthorized(statusCode, forUrl: fullUrl)) + simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -525,19 +533,22 @@ class BaseAppClient { } } - simplePut(String fullUrl, {Map body, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure}) async { + simplePut(String fullUrl, {Map body, Map headers, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure}) async { String url = fullUrl; print("URL Query String: $url"); if (await Utils.checkConnection()) { + headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.put( url.trim(), body: json.encode(body), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + headers: headers, ); final int statusCode = response.statusCode; print("statusCode :$statusCode"); + if(await handleUnauthorized(statusCode, forUrl: fullUrl)) + simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -549,7 +560,7 @@ class BaseAppClient { } } - simpleDelete(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams}) async { + simpleDelete(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { String url = fullUrl; print("URL Query String: $url"); @@ -561,13 +572,16 @@ class BaseAppClient { } if (await Utils.checkConnection()) { + headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.delete( url.trim(), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + headers: headers, ); final int statusCode = response.statusCode; print("statusCode :$statusCode"); + if(await handleUnauthorized(statusCode, forUrl: fullUrl)) + simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -579,6 +593,15 @@ class BaseAppClient { } } + Future handleUnauthorized(int statusCode, {String forUrl}) async{ + if(forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { + final token = await generatePackagesToken(); + packagesAuthHeader['Authorization'] = 'Bearer $token'; + return token != null && (token is String); + } + return false; + } + logout() async { await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID); @@ -770,4 +793,29 @@ class BaseAppClient { onFailure(e.toString(), -1); } } + + + + Future generatePackagesToken() async { + var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN; + var body = { + "api_client": { + "client_id": "a4ab6be4-424f-4836-b032-46caed88e184", + "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c" + } + }; + String token; + final completer = Completer(); + simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + token = jsonResponse['auth_token']; + completer.complete(); + } + }, onFailure: (String error, int statusCode) { + completer.complete(); + }); + await completer.future; + return token; + } } diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 479f59d3..dbc32029 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:developer'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; @@ -13,10 +14,15 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:flutter/cupertino.dart'; +var packagesAuthHeader = {'Authorization' : ''}; class OffersAndPackagesServices extends BaseService { + AuthenticatedUser patientUser; List categoryList = List(); List productList = List(); List latestOffersList = List(); @@ -25,13 +31,14 @@ class OffersAndPackagesServices extends BaseService { List cartItemList = List(); String cartItemCount = ""; + PackagesCustomerResponseModel customer; Future> getAllCategories(OffersCategoriesRequestModel request) async { Future errorThrow; var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['categories'].forEach((json) { @@ -39,7 +46,6 @@ class OffersAndPackagesServices extends BaseService { }); } }, onFailure: (String error, int statusCode) { - log(error); }, queryParams: request.toFlatMap()); return categoryList; @@ -52,7 +58,7 @@ class OffersAndPackagesServices extends BaseService { productList = List(); var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -60,7 +66,6 @@ class OffersAndPackagesServices extends BaseService { }); } }, onFailure: (String error, int statusCode) { - log(error); }, queryParams: request.toFlatMap()); return productList; @@ -69,7 +74,7 @@ class OffersAndPackagesServices extends BaseService { Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -86,7 +91,7 @@ class OffersAndPackagesServices extends BaseService { Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -103,7 +108,7 @@ class OffersAndPackagesServices extends BaseService { Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -121,6 +126,22 @@ class OffersAndPackagesServices extends BaseService { var finished = 0; var totalCalls = 3; + final auth_token = await baseAppClient.generatePackagesToken(); + if(auth_token == null){ + throw 'Something went wrong while authentication, Please try again letter'; + } + packagesAuthHeader["Authorization"] = 'Bearer $auth_token'; + + + // Check and Create Customer + if(patientUser != null){ + customer = await getCurrentCustomer(context: context, showLoading: showLoading); + if(customer == null){ + createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context); + } + } + + completedAll(){ finished++; @@ -162,24 +183,42 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; - await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ - _hideLoading(context, showLoading); + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ var jsonResponse = json.decode(stringResponse); var customerJson = jsonResponse['customers'].first; customer = PackagesCustomerResponseModel.fromJson(customerJson); }, onFailure: (String error, int statusCode){ - _hideLoading(context, showLoading); errorThrow = Future.error(error); log(error); }); + _hideLoading(context, showLoading); await Future.delayed(Duration(seconds: 1)); return errorThrow ?? customer; } + Future getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async{ + if(customer != null) + return Future.value(customer); + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}"; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ + var jsonResponse = json.decode(stringResponse); + var customerJson = jsonResponse['customers'].first; + customer = PackagesCustomerResponseModel.fromJson(customerJson); + + }, onFailure: (String error, int statusCode){ + log(error); + }); + + _hideLoading(context, showLoading); + return customer; + } + // -------------------- @@ -191,7 +230,7 @@ class OffersAndPackagesServices extends BaseService { cartItemList.clear(); _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -216,7 +255,7 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; - await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -237,7 +276,7 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient.simplePut(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -257,7 +296,7 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient.simpleDelete(url, onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ _hideLoading(context, showLoading); // var jsonResponse = json.decode(stringResponse); @@ -280,8 +319,8 @@ class OffersAndPackagesServices extends BaseService { "order": { "customer_id" : customer.id, "billing_address": { - "email": customer.email, - "phone_number": customer.addresses.first.phoneNumber + "email": patientUser.emailAddress, + "phone_number": patientUser.mobileNumber }, "payment_method_system_name": "Payments.PayFort", "payment_option": paymentOption @@ -291,7 +330,7 @@ class OffersAndPackagesServices extends BaseService { int order_id; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; - await baseAppClient.simplePost(url, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -312,7 +351,7 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id'; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); diff --git a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart index ad950b5d..1b68e9d7 100644 --- a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart +++ b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; class OfferCategoriesViewModel extends BaseViewModel{ OffersAndPackagesServices service = locator(); @@ -14,6 +15,7 @@ class OfferCategoriesViewModel extends BaseViewModel{ class PackagesViewModel extends BaseViewModel { OffersAndPackagesServices service = locator(); + List get categoryList => service.categoryList; List get productList => service.productList; List get latestOffersList => service.latestOffersList; diff --git a/lib/main.dart b/lib/main.dart index 49d37919..230e38dd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -144,6 +144,7 @@ class _MyApp extends State { // ), // ), initialRoute: SPLASH, + // initialRoute: OPENTOK_CALL_PAGE, // initialRoute: PACKAGES_OFFERS, // initialRoute: PACKAGES_ORDER_COMPLETED, routes: routes, diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index c6807ebb..7fcfecae 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -1,5 +1,6 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; @@ -280,7 +281,8 @@ class _HomePageFragment2State extends State { flex: 1, child: InkWell( onTap: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage())); + final user = projectViewModel.user; + Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user))); }, child: Container( width: double.infinity, diff --git a/lib/pages/packages_offers/CreateCustomerDailogPage.dart b/lib/pages/packages_offers/CreateCustomerDailogPage.dart index d7a98a64..70291a88 100644 --- a/lib/pages/packages_offers/CreateCustomerDailogPage.dart +++ b/lib/pages/packages_offers/CreateCustomerDailogPage.dart @@ -152,12 +152,12 @@ class _CreateCustomerDialogPageState extends State wit createCustomer() async{ setState(() => _enableInput = false); - loading(true); - var request = PackagesCustomerRequestModel(email: _emailTextController.text, phoneNumber: _phoneTextController.text); - viewModel().service - .createCustomer(request, context: context, showLoading: false) - .then((value) => success()) - .catchError((error) => showError(error)); + // loading(true); + // var request = PackagesCustomerRequestModel(email: _emailTextController.text, phoneNumber: _phoneTextController.text); + // viewModel().service + // .createCustomer(request, context: context, showLoading: false) + // .then((value) => success()) + // .catchError((error) => showError(error)); } diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart index b3b0605d..4005f835 100644 --- a/lib/pages/packages_offers/OfferAndPackagesPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -1,16 +1,22 @@ import 'package:after_layout/after_layout.dart'; import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/CreateCustomerDailogPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' as auth; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; @@ -26,8 +32,8 @@ import 'package:flutter_material_pickers/flutter_material_pickers.dart'; dynamic languageID; class PackagesHomePage extends StatefulWidget { - dynamic offersModel; - PackagesHomePage({@required this.offersModel}); + final AuthenticatedUser user; + PackagesHomePage(this.user); @override _PackagesHomePageState createState() => _PackagesHomePageState(); @@ -47,6 +53,7 @@ class _PackagesHomePageState extends State with AfterLayoutMix @override void afterFirstLayout(BuildContext context) async{ + viewModel.service.patientUser = widget.user; viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ setState((){}); }); @@ -81,9 +88,11 @@ class _PackagesHomePageState extends State with AfterLayoutMix } onProductCartClick(PackagesResponseModel product) async { - if(viewModel.service.customer == null) - viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); - + if(viewModel.service.customer == null) { + // viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); + loginCheck(context); + } + if(viewModel.service.customer != null) { var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); await viewModel.service.addProductToCart(request, context: context).then((response){ @@ -104,6 +113,8 @@ class _PackagesHomePageState extends State with AfterLayoutMix return appScaffold = AppScaffold( + description: TranslationBase.of(context).offerAndPackagesDetails, + imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')], appBarTitle: TranslationBase.of(context).offerAndPackages, isShowAppBar: true, isPharmacy: false, @@ -409,4 +420,33 @@ class _PackagesHomePageState extends State with AfterLayoutMix )), ); } + + + + loginCheck(context) async { + var data = await sharedPref.getObject(IMEI_USER_DATA); + sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); + if (data != null) { + Navigator.of(context).pushNamed(CONFIRM_LOGIN); + } else { + GifLoaderDialogUtils.showMyDialog(context); + + auth.AuthProvider().selectDeviceImei(DEVICE_TOKEN).then((SelectDeviceIMEIRES value) { + GifLoaderDialogUtils.hideDialog(context); + if (value != null) { + sharedPref.setObject(IMEI_USER_DATA, value); + Navigator.of(context).pushNamed(CONFIRM_LOGIN); + } else { + Navigator.of(context).pushNamed( + WELCOME_LOGIN, + ); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.of(context).pushNamed( + WELCOME_LOGIN, + ); + }); + } + } } diff --git a/lib/pages/webRTC/OpenTok/OpenTok.dart b/lib/pages/webRTC/OpenTok/OpenTok.dart new file mode 100644 index 00000000..7abcfca5 --- /dev/null +++ b/lib/pages/webRTC/OpenTok/OpenTok.dart @@ -0,0 +1,180 @@ +import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; + +import 'OpenTokPlatformBridge.dart'; + + +class OpenTokConnectCallPage extends StatefulWidget{ + final String sessionId; + final String token; + final String apiKey; + OpenTokConnectCallPage({@required this.sessionId, @required this.token, @required this.apiKey}); + + @override + State createState() => OpenTokState(); + +} + +class OpenTokState extends State{ + OpenTokPlatformBridge openTokPlatform; + OpenTokSDKState sdkState = OpenTokSDKState.LOGGED_OUT; + + initOpenTok(){ + openTokPlatform = OpenTokPlatformBridge.init( + apiKey: widget.apiKey, + sessionID: widget.sessionId, + token: widget.token, + onStateChange: (state) { + setState(() => sdkState = state); + } + ); + } + + @override + void initState() { + initOpenTok(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + extendBodyBehindAppBar: true, + appBar: AppBar( + backgroundColor: Colors.transparent, + actions: [ + TextButton(onPressed: (){ + initOpenTok(); + }, child: Icon(Icons.connect_without_contact_outlined, color: Colors.green,)) + ], + ), + body: Column( + children: [ + Expanded( + child: Stack( + children: [ + if(sdkState == OpenTokSDKState.LOGGED_IN) + ...platformVideoViews(), + + + if(sdkState == OpenTokSDKState.LOGGED_OUT) + Center(child: Text("Logged Out"),), + + if(sdkState == OpenTokSDKState.ERROR) + Center(child: Text("Error opening session"),), + + if(sdkState == OpenTokSDKState.WAIT) + Center(child: CircularProgressIndicator(),), + + if(sdkState == OpenTokSDKState.ON_CALL) + Container(), + ], + ), + ), + Row( + children: [ + Expanded( + child: ElevatedButton( + child: Text('Mute Video') ,onPressed: () => openTokPlatform.toggleVideo() + ), + ), + SizedBox(width: 20,), + Expanded( + child: ElevatedButton( + child: Text('Mute Audio') ,onPressed: () => openTokPlatform.toggleAudio() + ), + ), + SizedBox(width: 20,), + Expanded( + child: ElevatedButton( + child: Text('Change Camera') ,onPressed: () => openTokPlatform.swapCamera() + ), + ), + ], + ) + ], + ), + ); + } + + bool remoteVideoOnFull = true; + List platformVideoViews(){ + return [ + SizedBox( + width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, + child: remoteVideoOnFull ? remotePlatformVideoView() : localPlatformVideoView() + ), + + DraggablePublisher( + onButtonBarHeight: ((double)async*{}(50)), + onButtonBarVisible: ((bool)async*{}(true)), + availableScreenSize: MediaQuery.of(context).size, + child: InkWell( + child: (remoteVideoOnFull ? localPlatformVideoView() : remotePlatformVideoView()), + onTap: (){ + print(''); + }, + ), + ) + ]; + } + + Widget localPlatformVideoView(){ + return PlatformViewLink( + viewType: 'local-video-container', // custom platform-view-type + surfaceFactory: + (BuildContext context, PlatformViewController controller) { + return AndroidViewSurface( + controller: controller, + gestureRecognizers: const >{}, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, + + onCreatePlatformView: (PlatformViewCreationParams params) { + return PlatformViewsService.initSurfaceAndroidView( + id: params.id, + viewType: 'local-video-container', + // custom platform-view-type, + layoutDirection: TextDirection.ltr, + creationParams: {}, + creationParamsCodec: StandardMessageCodec(), + ) + ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) + ..create(); + }, + ); + } + + Widget remotePlatformVideoView(){ + return PlatformViewLink( + viewType: 'remote-video-container', // custom platform-view-type + surfaceFactory: + (BuildContext context, PlatformViewController controller) { + return AndroidViewSurface( + controller: controller, + gestureRecognizers: const >{}, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, + onCreatePlatformView: (PlatformViewCreationParams params) { + return PlatformViewsService.initSurfaceAndroidView( + id: params.id, + viewType: 'remote-video-container', + // custom platform-view-type, + layoutDirection: TextDirection.ltr, + creationParams: {}, + creationParamsCodec: StandardMessageCodec(), + ) + ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) + ..create(); + }, + ); + } + +} \ No newline at end of file diff --git a/lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart b/lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart new file mode 100644 index 00000000..bfdb8fb4 --- /dev/null +++ b/lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart @@ -0,0 +1,86 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:permission_handler/permission_handler.dart'; + +enum OpenTokSDKState{ LOGGED_OUT, LOGGED_IN, WAIT, ON_CALL, ERROR } +final _platformMethodChannel = const MethodChannel('OpenTok-Platform-Bridge'); + +class OpenTokPlatformBridge{ + + + OpenTokSDKState _sdkState = OpenTokSDKState.LOGGED_OUT; + bool _publishAudio = true; + bool _publishVideo = true; + + final void Function(OpenTokSDKState) onStateChange; + + OpenTokPlatformBridge.init({@required String sessionID, @required String token, @required String apiKey, this.onStateChange}){ + _initSession({'apiKey':apiKey, 'sessionId':sessionID, 'token':token, }); + _platformMethodChannel.setMethodCallHandler(incomingMethodHadler); + } + + Future incomingMethodHadler(MethodCall methodCall) async { + switch (methodCall.method) { + case 'updateState': + { + var arguments = 'OpenTokSDKState.${methodCall.arguments}'; + _sdkState = OpenTokSDKState.values.firstWhere((v) { + return v.toString() == arguments; + }); + onStateChange(_sdkState); + } + break; + default: + throw MissingPluginException('notImplemented'); + } + } + + + Future _initSession(Map openTokCredentials) async { + await requestPermissions(); + try { + await _platformMethodChannel.invokeMethod('initSession', openTokCredentials); + } on PlatformException catch (e) { + print(e); + } + } + + Future makeCall() async { + try { + await requestPermissions(); + + await _platformMethodChannel.invokeMethod('makeCall'); + } on PlatformException catch (e) { + print(e); + } + } + + Future requestPermissions() async { + await [Permission.microphone, Permission.camera].request(); + } + + Future swapCamera() async { + try { + await _platformMethodChannel.invokeMethod('swapCamera'); + } on PlatformException catch (e) {} + } + + Future toggleAudio() async { + _publishAudio = !_publishAudio; + dynamic params = {'publishAudio': _publishAudio}; + + try { + await _platformMethodChannel.invokeMethod('publishAudio', params); + } on PlatformException catch (e) {} + } + + Future toggleVideo() async { + _publishVideo = !_publishVideo; + dynamic params = {'publishVideo': _publishVideo}; + + try { + await _platformMethodChannel.invokeMethod('toggleVideo', params); + } on PlatformException catch (e) {} + } +} diff --git a/lib/routes.dart b/lib/routes.dart index 5d4ebea4..a8d850e1 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -20,6 +20,7 @@ import 'package:diplomaticquarterapp/pages/settings/settings.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/info.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/select-gender.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/symtom-checker.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; import 'package:diplomaticquarterapp/splashPage.dart'; const String INIT_ROUTE = '/'; @@ -45,6 +46,7 @@ const String PACKAGES_OFFERS = 'packages-offers'; const String PACKAGES_OFFERS_CART = 'packages-offers-cart'; const String PACKAGES_ORDER_COMPLETED = 'packages-offers-cart'; const String TEST_PAGE = 'test-page'; +const String OPENTOK_CALL_PAGE = 'OPENTOK_CALL_PAGE'; const String HEALTH_WEATHER = 'health-weather'; const APP_UPDATE = 'app-update'; @@ -66,11 +68,15 @@ var routes = { SYMPTOM_CHECKER_INFO: (_) => SymptomInfo(), SELECT_GENDER: (_) => SelectGender(), SETTINGS: (_) => Settings(), - PACKAGES_OFFERS: (_) => PackagesHomePage(), PACKAGES_OFFERS_CART: (_) => PackagesCartPage(), PACKAGES_ORDER_COMPLETED: (_) => PackageOrderCompletedPage(), TEST_PAGE: (_) => TestPage(), HEALTH_WEATHER: (_) => HealthWeatherIndicator(), APP_UPDATE: (_) => AppUpdatePage(), SETTINGS: (_) => Settings(), + OPENTOK_CALL_PAGE: (_) => OpenTokConnectCallPage( + apiKey: '46209962', + sessionId: '1_MX40NjIwOTk2Mn5-MTYzNDY0ODM3NDY2Nn5PcnpnNGM0R1Q3ODZ6UXlFQ01lMDF5YWJ-fg', + token: 'T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9Y2ZhZjMzZjA3MWFkMjkxN2JmYjEwZDkxYTRkOTdhN2NmNWE4YjMyYTpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWXpORFkwT0RNM05EWTJObjVQY25wbk5HTTBSMVEzT0RaNlVYbEZRMDFsTURGNVlXSi1mZyZjcmVhdGVfdGltZT0xNjM0NjQ4Mzc1Jm5vbmNlPTAuNzczMzcxNDUxMDgzMjQyMyZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjM0NzM0Nzc1JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9' + ), }; diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 09b50632..4d014a2f 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1387,6 +1387,7 @@ class TranslationBase { String get enablingWifi => localizedValues['enablingWifi'][locale.languageCode]; String get offerAndPackages => localizedValues['offerAndPackages'][locale.languageCode]; + String get offerAndPackagesDetails => localizedValues['offerAndPackagesDetails'][locale.languageCode]; String get invoiceNo => localizedValues['InvoiceNo'][locale.languageCode]; diff --git a/lib/widgets/offers_packages/PackagesCartItemCard.dart b/lib/widgets/offers_packages/PackagesCartItemCard.dart index 3ae405c6..c59c08cd 100644 --- a/lib/widgets/offers_packages/PackagesCartItemCard.dart +++ b/lib/widgets/offers_packages/PackagesCartItemCard.dart @@ -82,8 +82,8 @@ class PackagesCartItemCardState extends State { left: 10, child: Row( children: [ - _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), _totalLabel(context: context), + _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), ], ), ) From 1fff2dad251b2109fd6cdf0113e50061cb19e6a4 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 25 Oct 2021 16:21:27 +0300 Subject: [PATCH 14/60] Smartwatch updates --- assets/images/SmartWatches/distance.png | Bin 0 -> 3432 bytes assets/images/SmartWatches/steps.png | Bin 0 -> 2739 bytes lib/config/config.dart | 6 +- lib/config/localized_values.dart | 10 + lib/core/service/client/base_app_client.dart | 4 +- lib/core/viewModels/er/rrt-view-model.dart | 46 +- .../rapid-response-team/rrt-logs-page.dart | 9 +- .../rapid-response-team/rrt-main-screen.dart | 51 +- .../rrt-order-list-item.dart | 23 +- .../rapid-response-team/rrt-place-order.dart | 2 +- .../rapid-response-team/rrt-request-page.dart | 9 +- .../distance/distanceTracker.dart | 2 +- .../health_data_list.dart | 163 ++---- .../heartrate/heartrateTracker.dart | 2 +- .../smart_watch_instructions.dart | 547 ++++++------------ .../steps/stepsTracker.dart | 2 +- lib/uitl/translations_delegate_base.dart | 22 + 17 files changed, 373 insertions(+), 525 deletions(-) create mode 100644 assets/images/SmartWatches/distance.png create mode 100644 assets/images/SmartWatches/steps.png diff --git a/assets/images/SmartWatches/distance.png b/assets/images/SmartWatches/distance.png new file mode 100644 index 0000000000000000000000000000000000000000..d07f3e8aa96e286d21389001cb2e0a7142baf592 GIT binary patch literal 3432 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 literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index 7270f91e..d4ab58a9 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; @@ -452,6 +452,8 @@ const UPDATE_CMC_ORDER_RC = 'rc/api/cmc/update'; // RRT RC SERVICES const ADD_RRT_ORDER_RC = "rc/api/rrt/add"; +const GET_ALL_RRT_ORDERS_RC = "rc/api/rrt/list"; +const UPDATE_RRT_ORDER_RC = 'rc/api/rrt/update'; //Pharmacy wishlist const GET_WISHLIST = "shopping_cart_items/"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7584ec6e..d1f138e4 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1584,4 +1584,14 @@ const Map localizedValues = { "avgDistance": { "en": "Average Distance", "ar": "متوسط المسافة" }, "enterDetails": {"en": "Enter Details", "ar": "أدخل التفاصيل"}, "avgHeartRate": { "en": "Average Heart Rate", "ar": "متوسط معدل ضربات القلب" }, + "alreadySynced": { "en": "Already Synced", "ar": "متزامنة" }, + "sync-instructions-intro1": { "en": "It Seems like you haven't synced your health data with the Dr. Alhabib App before. To proceed further, you need to sync your health data with the Dr. Alhabib App", "ar": "يبدو أنك لم تقم بمزامنة بياناتك الصحية مع تطبيق Dr. Alhabib App من قبل. للمتابعة ، تحتاج إلى مزامنة بياناتك الصحية مع تطبيق Dr. Alhabib" }, + "sync-instructions-intro2": { "en": "Before syncing data, please make sure that you have followed the instructions properly", "ar": "قبل مزامنة البيانات ، يرجى التأكد من اتباع التعليمات بشكل صحيح." }, + "sync-instructions-intro3": { "en": "Before syncing data, please make sure that following instructions are met:", "ar": "قبل مزامنة البيانات ، يرجى التأكد من تلبية الإرشادات التالية:" }, + "ios-instructions-1": { "en": "Make sure that you have installed 'Health' App & 'Watch' App from Apple Store.", "ar": "تأكد من أنك قمت بتثبيت تطبيق 'Health' App & 'Watch' من متجر Apple." }, + "ios-instructions-2": { "en": "Make sure that your Apple Watch is connected with the Watch & Health Apps.", "ar": "تأكد من اتصال Apple Watch بتطبيقات Watch & Health." }, + "ios-instructions-3": { "en": "Make sure that data like heart rate, steps, distance etc. are being shown on your health app.", "ar": "تأكد من عرض بيانات مثل معدل ضربات القلب والخطوات والمسافة وما إلى ذلك على تطبيق صحتك." }, + "supportedWatches": { "en": "Supported SmartWatches", "ar": "الساعات الذكية المدعومة" }, + "watchInstructions": { "en": "Watch Instructions:", "ar": "تعليمات الساعة:" }, + "monthlyTab": {"en": "Monthly", "ar": "شهري"}, }; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 4f8a3f5d..c35be69b 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -114,8 +114,10 @@ class BaseAppClient { } } + // body['IdentificationNo'] = 1009199553; + // body['MobileNo'] = "966545156035"; // body['PatientID'] = 1018977; - body['TokenID'] = "@dm!n"; + // body['TokenID'] = "@dm!n"; body.removeWhere((key, value) => key == null || value == null); diff --git a/lib/core/viewModels/er/rrt-view-model.dart b/lib/core/viewModels/er/rrt-view-model.dart index 83732ebd..60411fab 100644 --- a/lib/core/viewModels/er/rrt-view-model.dart +++ b/lib/core/viewModels/er/rrt-view-model.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; @@ -17,8 +18,8 @@ import '../base_view_model.dart'; class RRTService extends BaseService {} class _RRTServiceData { - List pendingOrders = []; - List completedOrders = []; + List pendingOrders = []; + List completedOrders = []; ServicePrice servicePrice; } @@ -34,7 +35,8 @@ class RRTViewModel extends BaseViewModel { Future<_RRTServiceData> loadRequiredData() async { await getServicePrice(); - await getAllOrders(); + // await getAllOrders(); + await getAllOrdersRC(); return rrtServiceData; } @@ -79,9 +81,9 @@ class RRTViewModel extends BaseViewModel { if (json["ServiceID"] == 5) { if (json["Status"] == 1 || json["Status"] == 2) { // Pending - rrtServiceData.pendingOrders.add(PrescriptionsOrder.fromJson(json)); + rrtServiceData.pendingOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); } - rrtServiceData.completedOrders.add(PrescriptionsOrder.fromJson(json)); + rrtServiceData.completedOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); } }); } @@ -91,6 +93,26 @@ class RRTViewModel extends BaseViewModel { return rrtServiceData; } + Future<_RRTServiceData> getAllOrdersRC() async { + await _service.baseAppClient.post(GET_ALL_RRT_ORDERS_RC, body: {}, onSuccess: (response, statusCode) { + var data = response["response"]; + rrtServiceData.completedOrders.clear(); + rrtServiceData.pendingOrders.clear(); + if (data != null && data is List) { + data.forEach((json) { + if (json["StatusId"] == 1 || json["StatusId"] == 2) { + // Pending + rrtServiceData.pendingOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); + } + rrtServiceData.completedOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); + }); + } + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + }); + return rrtServiceData; + } + Future getOrderDetails() async { return null; } @@ -136,6 +158,19 @@ class RRTViewModel extends BaseViewModel { return Future.value(success); } + Future cancelOrderRC(GetCMCAllOrdersResponseModel order, {String reason = ""}) async { + Map body = {"Id": order.iD, "ClickButton": 16}; + var success = false; + await _service.baseAppClient.post(UPDATE_RRT_ORDER_RC, body: body, onSuccess: (response, statusCode) { + success = true; + rrtServiceData.pendingOrders.remove(order); + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + success = false; + }); + return Future.value(success); + } + Future> getAddresses() async { Object error; try { @@ -175,7 +210,6 @@ class RRTViewModel extends BaseViewModel { await getCustomerAddresses(); } - // setState(ViewState.Busy); // await _pharmacy_service.generatePharmacyToken(); // if (_customerAddressesService.hasError) { diff --git a/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart index c7c12a2d..2a1dd3c9 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-order-list-item.dart'; @@ -11,7 +12,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; class RRTLogPage extends StatefulWidget { - final List orders; + final List orders; const RRTLogPage({this.orders}); @@ -45,13 +46,13 @@ class RRTLogPageState extends State { }); } - deleteOrder(PrescriptionsOrder order) async { + deleteOrder(GetCMCAllOrdersResponseModel order) async { GifLoaderDialogUtils.showMyDialog(context); - var success = await viewModel.cancelOrder(order); + var success = await viewModel.cancelOrderRC(order); if (success) { viewModel.setState(ViewState.Busy); - await viewModel.getAllOrders(); + await viewModel.getAllOrdersRC(); viewModel.setState(ViewState.Idle); Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RRTMainScreen)); Navigator.push(context, FadePage(page: RRTMainScreen())); diff --git a/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart index 351c918a..62fa4745 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-logs-page.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-request-page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; @@ -7,10 +8,13 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class RRTMainScreen extends StatefulWidget { final index = 0; + RRTMainScreen({index}); + @override State createState() => RRTMainScreenState(); } @@ -25,6 +29,8 @@ class RRTMainScreenState extends State with SingleTickerProviderS List imagesInfo = List(); + ProjectViewModel projectViewModel; + @override void initState() { super.initState(); @@ -36,6 +42,7 @@ class RRTMainScreenState extends State with SingleTickerProviderS @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); localize = TranslationBase.of(context); return AppScaffold( @@ -80,20 +87,40 @@ class RRTMainScreenState extends State with SingleTickerProviderS margin: EdgeInsets.all(0.0), clipBehavior: Clip.hardEdge, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10)), - child: TabBar(onTap: onPageChanged, indicatorWeight: 3, indicatorColor: Color(0xFFc5272d), isScrollable: false, controller: tabController, indicatorSize: TabBarIndicatorSize.label, tabs: [ - Tab( - child: Text( - localize.rapidResponseTeam, - style: TextStyle(color: Theme.of(context).appBarTheme.color), + child: TabBar( + onTap: onPageChanged, + controller: tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 5, bottom: 5), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), - ), - Tab( - child: Text( - localize.orderLog, - style: TextStyle(color: Theme.of(context).appBarTheme.color), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), - ), - ]), + tabs: [ + Tab( + child: Text( + localize.rapidResponseTeam, + style: TextStyle(color: Theme.of(context).appBarTheme.color), + ), + ), + Tab( + child: Text( + localize.orderLog, + style: TextStyle(color: Theme.of(context).appBarTheme.color), + ), + ), + ]), ); Widget contentPager() => PageView( diff --git a/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart b/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart index a2ef7cd0..8a4f1e18 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -16,8 +17,8 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart'; final _item_content_seperator = Container(height: 0.25, padding: EdgeInsets.all(10), color: Colors.grey.withOpacity(0.5)); class RRTLogListItem extends StatefulWidget { - final PrescriptionsOrder order; - final Function(PrescriptionsOrder) onCancel; + final GetCMCAllOrdersResponseModel order; + final Function(GetCMCAllOrdersResponseModel) onCancel; RRTLogListItem(this.order, {this.onCancel}); @override @@ -34,8 +35,8 @@ class RRTLogListItemState extends State { ProjectViewModel projectViewModel = Provider.of(context); localize = TranslationBase.of(context); - int status = widget.order.status; - String _statusDisp = projectViewModel.isArabic ? widget.order.descriptionN : widget.order.description; + int status = widget.order.statusId; + String _statusDisp = widget.order.statusText; Color _color; if (status == 1) { //pending @@ -46,7 +47,7 @@ class RRTLogListItemState extends State { } else if (status == 3) { //completed _color = Color(0xff359846); - } else if (status == 4) { + } else if (status == 4 || status == 6 || status == 7) { //cancel // Rejected _color = Color(0xffD02127); } @@ -111,7 +112,7 @@ class RRTLogListItemState extends State { ), Expanded( child: Text( - !projectViewModel.isArabic ? widget.order.nearestProjectDescription.trim().toString() : widget.order.nearestProjectDescriptionN.toString(), + widget.order.projectName.toString(), style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), ), @@ -126,7 +127,7 @@ class RRTLogListItemState extends State { ), Expanded( child: Text( - widget.order.getFormattedDateTime(), + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.order.created)), style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), ), @@ -140,11 +141,11 @@ class RRTLogListItemState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - DateUtil.getDayMonthYearDateFormattedLang(widget.order.createdOn, projectViewModel.isArabic), + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.order.created)), style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), ), SizedBox(height: 12), - if (widget.order.status == 1 || widget.order.status == 2) + if (widget.order.statusId == 1 || widget.order.statusId == 2) InkWell( onTap: () { //onCancel(order); @@ -227,11 +228,11 @@ class RRTLogListItemState extends State { // ); cancelOrders(order) async { GifLoaderDialogUtils.showMyDialog(context); - var success = await viewModel.cancelOrder(order); + var success = await viewModel.cancelOrderRC(order); if (success) { viewModel.setState(ViewState.Busy); - await viewModel.getAllOrders(); + await viewModel.getAllOrdersRC(); viewModel.setState(ViewState.Idle); Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RRTMainScreen)); Navigator.push(context, FadePage(page: RRTMainScreen())); diff --git a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart index 4e863bd1..938b0528 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart @@ -217,7 +217,7 @@ class RRTPlaceOrderPage extends StatelessWidget { gotoRRTRoot() async { viewModel.setState(ViewState.Busy); - await viewModel.getAllOrders(); + await viewModel.getAllOrdersRC(); viewModel.setState(ViewState.Idle); Navigator.popUntil(_context, (route) => Utils.route(route, equalsTo: RRTMainScreen)); Navigator.push(_context, FadePage(page: RRTMainScreen())); diff --git a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart index 28cd3cf4..1848f52c 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; @@ -15,7 +16,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class RRTRequestPage extends StatefulWidget { - final List pendingOrders; + final List pendingOrders; final ServicePrice servicePrice; RRTRequestPage({this.pendingOrders, this.servicePrice}); @@ -208,14 +209,14 @@ class RRTRequestPageState extends State { ))); } - deleteOrder(PrescriptionsOrder order) async { + deleteOrder(GetCMCAllOrdersResponseModel order) async { GifLoaderDialogUtils.showMyDialog(context); - var success = await viewModel.cancelOrder(order); + var success = await viewModel.cancelOrderRC(order); GifLoaderDialogUtils.hideDialog(context); if (success) setState(() { widget.pendingOrders.remove(order); }); - await viewModel.getAllOrders(); + await viewModel.getAllOrdersRC(); } } diff --git a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart index 787bc210..cceb8b1e 100644 --- a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart @@ -89,7 +89,7 @@ class _DistanceTrackerState extends State with SingleTickerProv ), tabs: [ Tab(text: TranslationBase.of(context).weekly), - Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).monthlyTab), Tab(text: TranslationBase.of(context).yearly), ], onTap: (value) { diff --git a/lib/pages/medical/smart_watch_health_data/health_data_list.dart b/lib/pages/medical/smart_watch_health_data/health_data_list.dart index f63e3151..f43a6e63 100644 --- a/lib/pages/medical/smart_watch_health_data/health_data_list.dart +++ b/lib/pages/medical/smart_watch_health_data/health_data_list.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/dista import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -30,118 +31,35 @@ class _HealthDataListState extends State { @override Widget build(BuildContext context) { + List myMedicalList = myOptionsList(context); return AppScaffold( appBarTitle: TranslationBase.of(context).smartWatches, isShowAppBar: true, showNewAppBar: true, showNewAppBarTitle: true, body: Container( - height: MediaQuery.of(context).size.height, - margin: EdgeInsets.all(20.0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: HeartRateTracker(), - ), - ); - }, - child: Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text(TranslationBase.of(context).heart, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - ), - Divider( - color: Colors.grey[500], - ), - Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/sleep_data.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Sleep Data", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + Container( + width: double.infinity, + height: 20, ), - Divider( - color: Colors.grey[500], - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: StepsTracker(), - ), - ); - }, - child: Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text(TranslationBase.of(context).steps, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + Padding( + padding: EdgeInsets.only(left: 12, right: 12), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: myMedicalList.length, + itemBuilder: (BuildContext context, int index) { + return myMedicalList[index]; + }, ), ), - Divider( - color: Colors.grey[500], - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: DistanceTracker(), - ), - ); - }, - child: Row( - children: [ - Container( - child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text(TranslationBase.of(context).distance, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], - ), - ), - Divider( - color: Colors.grey[500], - ), - // Row( - // children: [ - // Container( - // child: Image.asset("assets/images/SmartWatches/heartrate_icon.png", width: 60.0, height: 60.0), - // ), - // Container( - // margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - // child: Text("Energy", style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - // ), - // ], - // ), - // Divider( - // color: Colors.grey[500], - // ), ], ), ), @@ -159,6 +77,53 @@ class _HealthDataListState extends State { ); } + + List myOptionsList(BuildContext context) { + List medical = List(); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: HeartRateTracker()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).heart, + imagePath: 'assets/images/SmartWatches/heartrate_icon.png', + subTitle: null, + isPngImage: true, + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: StepsTracker()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).steps, + imagePath: 'assets/images/SmartWatches/steps.png', + subTitle: null, + isPngImage: true, + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: DistanceTracker()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).distance, + imagePath: 'assets/images/SmartWatches/distance.png', + subTitle: null, + isPngImage: true, + ), + )); + + return medical; + } + + // void readLast() async { // print("ReadLast"); // final result = await FitKit.readLast(DataType.DISTANCE); diff --git a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart index 1c109669..da82d540 100644 --- a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart @@ -89,7 +89,7 @@ class _HeartRateTrackerState extends State with SingleTickerPr ), tabs: [ Tab(text: TranslationBase.of(context).weekly), - Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).monthlyTab), Tab(text: TranslationBase.of(context).yearly), ], onTap: (value) { diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index b4471611..4c515e3a 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -8,6 +8,8 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/healt import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchIntegrationService.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -24,13 +26,12 @@ class _SmartWatchInstructionsState extends State { bool hasAlreadySynced = false; - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - if(authenticatedUserObject.isLogin) getLastPatientRecord(context); + if (authenticatedUserObject.isLogin) getLastPatientRecord(context); }); super.initState(); } @@ -49,9 +50,7 @@ class _SmartWatchInstructionsState extends State { ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/1.png') ], body: Container( - child: Platform.isIOS - ? _getAppleWatchInstructions() - : _getGoogleWatchInstructions(), + child: Platform.isIOS ? _getAppleWatchInstructions() : _getGoogleWatchInstructions(), )); } @@ -65,10 +64,7 @@ class _SmartWatchInstructionsState extends State { // margin: EdgeInsets.only(top: 10.0), child: CarouselSlider( carouselController: buttonCarouselController, - options: CarouselOptions( - enableInfiniteScroll: false, - viewportFraction: 0.95, - height: MediaQuery.of(context).size.height * 0.9), + options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.9), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { @@ -83,33 +79,24 @@ class _SmartWatchInstructionsState extends State { ), child: i == 1 ? Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0), - child: Text("Supported Smartwatches", - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold)), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), ), Container( child: Row( children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 10.0), + margin: EdgeInsets.only(top: 10.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/apple-watch-1.jpeg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/apple-watch-1.jpeg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 1", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 1", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -117,20 +104,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 10.0), + margin: EdgeInsets.only(top: 10.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/apple-watch-2.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/apple-watch-2.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 2", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -145,20 +125,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/apple-watch-3.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/apple-watch-3.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 3", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -166,20 +139,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/apple-watch-4.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/apple-watch-4.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 4", overflow: TextOverflow.clip , - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -194,20 +160,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/apple-watch-5.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/apple-watch-5.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 5", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 5", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -215,20 +174,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/Apple-Watch-6.png", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/Apple-Watch-6.png", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Apple Watch Series 6", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 6", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -243,19 +195,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/miBand3.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Mi Band 3", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -263,19 +209,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/miBand4.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Mi Band 4", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -285,143 +225,78 @@ class _SmartWatchInstructionsState extends State { ), ), Container( - margin: EdgeInsets.fromLTRB( - 10.0, 30.0, 10.0, 10.0), - child: Text( - "It Seems like you haven't synced your health data with the Dr. Alhabib App before. To proceed further, you need to sync your health data with the Dr. Alhabib App", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "Before syncing data, please make sure that you have followed the instructions properly", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), - ), - minWidth: - MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("CONTINUE", - style: TextStyle(fontSize: 18.0)), - ), + margin: EdgeInsets.fromLTRB(15.0, 40.0, 15.0, 0.0), + child: DefaultButton( + TranslationBase.of(context).continues, + () { + buttonCarouselController.nextPage(); + }, + color: Color(0xff359846), ), ), ], ) : Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0), - child: Text("Watch Instructions:", - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold, - fontFamily: "WorkSans")), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).watchInstructions, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text( - "It Seems like you haven't synced your health data with the Dr. Alhabib App before. To proceed further, you need to sync your health data with the Dr. Alhabib App", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.fromLTRB( - 10.0, 20.0, 10.0, 10.0), - child: Text( - "Before syncing data, please make sure that following instructions are met: ", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.fromLTRB( - 10.0, 20.0, 10.0, 10.0), - child: Text( - "1. Make sure that you have installed 'Health' App & 'Watch' App from Apple Store.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).iosInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text( - "2. Make sure that your Apple Watch is connected with the Watch & Health Apps.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).iosInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text( - "3. Make sure that data like heart rate, steps, distance etc. are being shown on your health app.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).iosInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), - Container( - margin: EdgeInsets.fromLTRB( - 15.0, 80.0, 15.0, 15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), - ), - minWidth: - MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("SYNC HEALTH DATA", - style: TextStyle(fontSize: 18.0)), - ), + Padding( + padding: const EdgeInsets.fromLTRB(12.0, 50.0, 12.0, 20.0), + child: Row( + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).syncHealthData, + () {}, + color: Color(0xFFD02127), + disabledColor: Color(0xff28323A).withOpacity(0.3), + ), + ), + mWidth(12), + if (hasAlreadySynced) + Expanded( + child: DefaultButton( + TranslationBase.of(context).alreadySynced, + () { + _openHealthDataList(); + }, + color: Color(0xff359846), + ), + ), + ], ), ), - hasAlreadySynced ? Container( - margin: EdgeInsets.fromLTRB( - 15.0, 0.0, 15.0, 15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), - ), - minWidth: - MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - _openHealthDataList(); - }, - child: Text("ALREADY SYNCED", - style: TextStyle(fontSize: 18.0)), - ), - ), - ): Container(), ], ), )); @@ -447,7 +322,7 @@ class _SmartWatchInstructionsState extends State { options: CarouselOptions( // enableInfiniteScroll: true, viewportFraction: 0.99, - height: MediaQuery.of(context).size.height*1.1 ), + height: MediaQuery.of(context).size.height * 0.9), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { @@ -455,7 +330,7 @@ class _SmartWatchInstructionsState extends State { width: MediaQuery.of(context).size.width, margin: EdgeInsets.symmetric(horizontal: 5.0), child: Card( - margin: EdgeInsets.only(top:16.0 , bottom: 8.0), + margin: EdgeInsets.only(top: 16.0, bottom: 8.0), // fromLTRB(8.0, 16.0, 8.0, 8.0), color: Colors.white.withOpacity(1.0), shape: RoundedRectangleBorder( @@ -466,31 +341,20 @@ class _SmartWatchInstructionsState extends State { children: [ Container( margin: EdgeInsets.only(top: 10.0), - child: Text("Supported Smartwatches", - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold, - fontFamily: "WorkSans")), + child: Text("Supported Smartwatches", style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold, fontFamily: "WorkSans")), ), Container( child: Row( children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 10.0), + margin: EdgeInsets.only(top: 10.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/huawei-watch-2.png", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/huawei-watch-2.png", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Huawei Watch 2", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Huawei Watch 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -498,21 +362,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 10.0), + margin: EdgeInsets.only(top: 10.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/ticwatche2.png", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "Mobovi TicWatch E2", - overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mobovi TicWatch E2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -527,19 +383,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/huawei-watch-2-classic.png", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/huawei-watch-2-classic.png", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Huawei Watch", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Huawei Watch", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -547,19 +397,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/ticwatche2.png", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Fossil Sport", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Fossil Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -574,20 +418,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/misfit-vapor-2.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/misfit-vapor-2.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "MisFit Vapor 2", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("MisFit Vapor 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -595,20 +432,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/lg-watch-sport.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/lg-watch-sport.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text( - "LG Watch Sport", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("LG Watch Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -623,19 +453,13 @@ class _SmartWatchInstructionsState extends State { children: [ Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/miBand3.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Mi Band 3", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -643,19 +467,13 @@ class _SmartWatchInstructionsState extends State { ), Expanded( child: Container( - margin: - EdgeInsets.only(top: 15.0), + margin: EdgeInsets.only(top: 15.0), child: Row( children: [ - Image.asset( - "assets/images/SmartWatches/miBand4.jpg", - width: 70.0, - height: 70.0), + Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), Container( - width: MediaQuery.of(context).size.width*0.22, - child: Text("Mi Band 4", overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 12.0)), + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ) ], ), @@ -666,18 +484,11 @@ class _SmartWatchInstructionsState extends State { ), InkWell( onTap: () { - launch( - "https://wearos.google.com/#find-your-watch"); + launch("https://wearos.google.com/#find-your-watch"); }, child: Container( margin: EdgeInsets.only(top: 20.0), - child: Text( - "More Supported Smartwatches...", - style: TextStyle( - fontSize: 17.0, - color: Colors.blue, - decoration: - TextDecoration.underline)), + child: Text("More Supported Smartwatches...", style: TextStyle(fontSize: 17.0, color: Colors.blue, decoration: TextDecoration.underline)), ), ), Container( @@ -689,20 +500,16 @@ class _SmartWatchInstructionsState extends State { ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "Before syncing data, please make sure that you have followed the instructions properly", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: + Text("Before syncing data, please make sure that you have followed the instructions properly", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( margin: EdgeInsets.all(15.0), child: ButtonTheme( shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), + borderRadius: BorderRadius.circular(10.0), ), - minWidth: - MediaQuery.of(context).size.width, + minWidth: MediaQuery.of(context).size.width, height: 45.0, child: RaisedButton( color: new Color(0xFF60686b), @@ -713,8 +520,7 @@ class _SmartWatchInstructionsState extends State { onPressed: () { buttonCarouselController.nextPage(); }, - child: Text("CONTINUE", - style: TextStyle(fontSize: 18.0)), + child: Text("CONTINUE", style: TextStyle(fontSize: 18.0)), ), ), ), @@ -724,11 +530,7 @@ class _SmartWatchInstructionsState extends State { children: [ Container( margin: EdgeInsets.only(top: 10.0), - child: Text("Watch Instructions:", - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold, - fontFamily: "WorkSans")), + child: Text("Watch Instructions:", style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold, fontFamily: "WorkSans")), ), Container( margin: EdgeInsets.all(10.0), @@ -739,49 +541,33 @@ class _SmartWatchInstructionsState extends State { ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "Before syncing data, please make sure that following instructions are met: ", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text("Before syncing data, please make sure that following instructions are met: ", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "1. Make sure that you have installed 'WearOS' & 'Google Fit' apps from Google PlayStore.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text("1. Make sure that you have installed 'WearOS' & 'Google Fit' apps from Google PlayStore.", + textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "2. Make sure that you have installed your watch related apps from Google PlayStore.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text("2. Make sure that you have installed your watch related apps from Google PlayStore.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "3. Make sure that your Smart Watch is connected with the WearOS app & your watch apps.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: + Text("3. Make sure that your Smart Watch is connected with the WearOS app & your watch apps.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "4. Make sure that your smart watch apps are linked/associated with Google Fit App.", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text("4. Make sure that your smart watch apps are linked/associated with Google Fit App.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), ), Container( - margin: EdgeInsets.fromLTRB( - 15.0, 75.0, 15.0, 15.0), + margin: EdgeInsets.fromLTRB(15.0, 75.0, 15.0, 15.0), child: ButtonTheme( shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), + borderRadius: BorderRadius.circular(10.0), ), - minWidth: - MediaQuery.of(context).size.width, + minWidth: MediaQuery.of(context).size.width, height: 45.0, child: RaisedButton( color: new Color(0xFF60686b), @@ -792,36 +578,33 @@ class _SmartWatchInstructionsState extends State { onPressed: () { buttonCarouselController.nextPage(); }, - child: Text("SYNC HEALTH DATA", - style: TextStyle(fontSize: 18.0)), + child: Text("SYNC HEALTH DATA", style: TextStyle(fontSize: 18.0)), ), ), ), - hasAlreadySynced ? Container( - margin: EdgeInsets.fromLTRB( - 15.0, 0.0, 15.0, 15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), - ), - minWidth: - MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - _openHealthDataList(); - }, - child: Text("ALREADY SYNCED", - style: TextStyle(fontSize: 18.0)), - ), - ), - ) : Container(), + hasAlreadySynced + ? Container( + margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 15.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + elevation: 0, + disabledTextColor: Colors.white, + disabledColor: new Color(0xFFbcc2c4), + onPressed: () { + _openHealthDataList(); + }, + child: Text("ALREADY SYNCED", style: TextStyle(fontSize: 18.0)), + ), + ), + ) + : Container(), ], ), )); diff --git a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart index c1be5f2d..5f63c2ad 100644 --- a/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart @@ -89,7 +89,7 @@ class _StepsTrackerState extends State with SingleTickerProviderSt ), tabs: [ Tab(text: TranslationBase.of(context).weekly), - Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).monthlyTab), Tab(text: TranslationBase.of(context).yearly), ], onTap: (value) { diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index d61b4f10..e82c6521 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2484,7 +2484,9 @@ class TranslationBase { String get mostViewed => localizedValues["mostViewed"][locale.languageCode]; String get newProducts => localizedValues["newProducts"][locale.languageCode]; + String get enterDetails => localizedValues["enterDetails"][locale.languageCode]; + String get paymentSelected => localizedValues["paymentSelected"][locale.languageCode]; String get moreNotifications => localizedValues["moreNotifications"][locale.languageCode]; @@ -2530,6 +2532,26 @@ class TranslationBase { String get avgDistance => localizedValues["avgDistance"][locale.languageCode]; String get avgHeartRate => localizedValues["avgHeartRate"][locale.languageCode]; + + String get alreadySynced => localizedValues["alreadySynced"][locale.languageCode]; + + String get syncInstructionsIntro1 => localizedValues["sync-instructions-intro1"][locale.languageCode]; + + String get syncInstructionsIntro2 => localizedValues["sync-instructions-intro2"][locale.languageCode]; + + String get syncInstructionsIntro3 => localizedValues["sync-instructions-intro3"][locale.languageCode]; + + String get iosInstructions1 => localizedValues["ios-instructions-1"][locale.languageCode]; + + String get iosInstructions2 => localizedValues["ios-instructions-2"][locale.languageCode]; + + String get iosInstructions3 => localizedValues["ios-instructions-3"][locale.languageCode]; + + String get supportedWatches => localizedValues["supportedWatches"][locale.languageCode]; + + String get watchInstructions => localizedValues["watchInstructions"][locale.languageCode]; + + String get monthlyTab => localizedValues["monthlyTab"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 551475328893121d0329e55ed54e53d7beddfcad Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Mon, 25 Oct 2021 17:10:08 +0300 Subject: [PATCH 15/60] Zoom Avatar implementation --- .../prescription_details_page.dart | 54 ++++++++++---- .../prescription_items_page.dart | 72 +++++++++++++------ lib/widgets/avatar/large_avatar.dart | 42 ++++++----- .../medical/time_line_new_widget.dart | 1 + lib/widgets/hospital_location.dart | 14 ++-- lib/widgets/show_zoom_image_dialog.dart | 48 +++++++++++++ 6 files changed, 170 insertions(+), 61 deletions(-) create mode 100644 lib/widgets/show_zoom_image_dialog.dart diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart index ebc3c241..3fbc2baf 100644 --- a/lib/pages/medical/prescriptions/prescription_details_page.dart +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -10,9 +10,11 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/show_zoom_image_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -78,20 +80,46 @@ class PrescriptionDetailsPage extends StatelessWidget { children: [ Row( children: [ - Container( - decoration: BoxDecoration( - border: Border.all(width: 1.0, color: Color(0xffEBEBEB)), - borderRadius: BorderRadius.all(Radius.circular(30.0)), - ), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: Image.network( - prescriptionReport.imageSRCUrl, - fit: BoxFit.cover, - width: 48, - height: 48, - ), + // Container( + // decoration: BoxDecoration( + // border: Border.all(width: 1.0, color: Color(0xffEBEBEB)), + // borderRadius: BorderRadius.all(Radius.circular(30.0)), + // ), + // child: ClipRRect( + // borderRadius: BorderRadius.all(Radius.circular(30)), + // child: Image.network( + // prescriptionReport.imageSRCUrl, + // fit: BoxFit.cover, + // width: 48, + // height: 48, + // ), + // ), + // ), + InkWell( + child: Stack( + alignment: Alignment.center, + children: [ + Container( + child: Image.network( + prescriptionReport.imageSRCUrl, + fit: BoxFit.cover, + width: 48, + height: 49, + ), + margin: EdgeInsets.zero, + clipBehavior: Clip.antiAlias, + decoration: cardRadius(2000), + ), + Container( + child: Icon(Icons.search,size: 18,color: Colors.white,), + padding: EdgeInsets.all(6), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), + onTap: (){ + showZoomImageDialog(context, prescriptionReport.imageSRCUrl); + }, ), SizedBox(width: 12), Expanded( diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart index 6e30a3f7..4611eed1 100644 --- a/lib/pages/medical/prescriptions/prescription_items_page.dart +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -14,6 +14,7 @@ import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/show_zoom_image_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -37,7 +38,6 @@ class PrescriptionItemsPage extends StatelessWidget { appBarTitle: prescriptions.doctorName, baseViewModel: model, showNewAppBar: true, - backgroundColor: Color(0xffF8F8F8), showNewAppBarTitle: true, body: Column( children: [ @@ -108,20 +108,31 @@ class PrescriptionItemsPage extends StatelessWidget { mHeight(10), Row( children: [ - Container( - child: Container( - child: Image.network( - model.prescriptionReportListINP[index].imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 60, - ), - margin: EdgeInsets.zero, - clipBehavior: Clip.antiAlias, - decoration: cardRadius(2000), + InkWell( + child: Stack( + alignment: Alignment.center, + children: [ + Container( + child: Image.network( + model.prescriptionReportListINP[index].imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 60, + ), + margin: EdgeInsets.zero, + clipBehavior: Clip.antiAlias, + decoration: cardRadius(2000), + ), + Container( + child: Icon(Icons.search,size: 18,color: Colors.white,), + padding: EdgeInsets.all(6), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), - clipBehavior: Clip.antiAlias, - decoration: containerColorRadiusBorderWidth(Colors.white, 200, Colors.grey[200], 1), + onTap: (){ + showZoomImageDialog(context, model.prescriptionReportListINP[index].imageSRCUrl,); + }, ), mWidth(12), Column( @@ -269,16 +280,31 @@ class PrescriptionItemsPage extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - child: Image.network( - model.prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 48, - height: 48, + InkWell( + child: Stack( + alignment: Alignment.center, + children: [ + Container( + child: Image.network( + model.prescriptionReportEnhList[index].imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 60, + ), + margin: EdgeInsets.zero, + clipBehavior: Clip.antiAlias, + decoration: cardRadius(2000), + ), + Container( + child: Icon(Icons.search,size: 18,color: Colors.white,), + padding: EdgeInsets.all(6), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), - margin: EdgeInsets.zero, - clipBehavior: Clip.antiAlias, - decoration: cardRadius(2000), + onTap: (){ + showZoomImageDialog(context, model.prescriptionReportEnhList[index].imageSRCUrl,); + }, ), mWidth(12), Expanded( diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart index e1f395d8..64b72f2b 100644 --- a/lib/widgets/avatar/large_avatar.dart +++ b/lib/widgets/avatar/large_avatar.dart @@ -1,7 +1,10 @@ +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../show_zoom_image_dialog.dart'; + /// LargeAvatar /// [name] the user name /// [url] the image url @@ -11,16 +14,7 @@ import 'package:flutter/material.dart'; /// [height] the avatar height /// [onTap] on tap function class LargeAvatar extends StatelessWidget { - LargeAvatar( - {Key key, - @required this.name, - this.url, - this.disableProfileView: false, - this.radius = 70.0, - this.width = 70, - this.height = 60, - this.onTap}) - : super(key: key); + LargeAvatar({Key key, @required this.name, this.url, this.disableProfileView: false, this.radius = 70.0, this.width = 70, this.height = 60, this.onTap}) : super(key: key); final String name; final String url; @@ -35,11 +29,22 @@ class LargeAvatar extends StatelessWidget { return Center( child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(radius)), - child: Image.network( - url.trim(), - fit: BoxFit.fill, - width: width, - height: height, + child: Stack( + alignment: Alignment.center, + children: [ + Image.network( + url.trim(), + fit: BoxFit.fill, + width: width, + height: height, + ), + if (!disableProfileView) + Container( + child: Icon(Icons.search,size: 18,color: Colors.white,), + padding: EdgeInsets.all(6), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), ), ); @@ -55,7 +60,12 @@ class LargeAvatar extends StatelessWidget { @override Widget build(BuildContext context) { return InkWell( - onTap: disableProfileView ? null : onTap, + onTap: disableProfileView + ? null + : () { + print("ssssss " + url.trim()); + showZoomImageDialog(context, url.trim() ?? ""); + }, child: Container( decoration: BoxDecoration( // gradient: LinearGradient( diff --git a/lib/widgets/data_display/medical/time_line_new_widget.dart b/lib/widgets/data_display/medical/time_line_new_widget.dart index a7d180c5..3851f329 100644 --- a/lib/widgets/data_display/medical/time_line_new_widget.dart +++ b/lib/widgets/data_display/medical/time_line_new_widget.dart @@ -351,6 +351,7 @@ class TimelineNewWidget extends StatelessWidget { ))); }, name: appoitmentAllHistoryResul.doctorNameObj, + disableProfileView: true, url: appoitmentAllHistoryResul.doctorImageURL, width: 30, height: 30, diff --git a/lib/widgets/hospital_location.dart b/lib/widgets/hospital_location.dart index dd70d06f..986daa6c 100644 --- a/lib/widgets/hospital_location.dart +++ b/lib/widgets/hospital_location.dart @@ -1,11 +1,14 @@ import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/show_zoom_image_dialog.dart'; import 'package:flutter/material.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'avatar/large_avatar.dart'; import 'my_rich_text.dart'; class HospitalLocation extends StatelessWidget { @@ -46,15 +49,8 @@ class HospitalLocation extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ClipRRect( - borderRadius: BorderRadius.circular(30), - child: Image.network( - location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg', - width: 48, - height: 48, - fit: BoxFit.cover, - ), - ), + LargeAvatar(url: location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg',width: 48,height: 48, name: "",), + SizedBox(width: 10), Expanded( child: Column( diff --git a/lib/widgets/show_zoom_image_dialog.dart b/lib/widgets/show_zoom_image_dialog.dart new file mode 100644 index 00000000..2340c259 --- /dev/null +++ b/lib/widgets/show_zoom_image_dialog.dart @@ -0,0 +1,48 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; +import 'package:progress_hud_v2/generated/i18n.dart'; + +showZoomImageDialog(BuildContext context, String url) { + showDialog( + context: context, + builder: (BuildContext context) => Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.0), + ), //this right here + child: ShowZoomImage(url), + ), + ); +} + +class ShowZoomImage extends StatelessWidget { + String url; + + ShowZoomImage(this.url); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + IconButton( + icon: Icon(Icons.close), + onPressed: () { + Navigator.pop(context); + }, + ), + CachedNetworkImage( + imageUrl: url, + height: MediaQuery.of(context).size.width / 1.4, + width: double.infinity, + ), + mHeight(12), + ], + ), + ); + } +} From 7c4edf971af295a7c2e0dc8f2bdd0a741f127607 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 25 Oct 2021 17:15:04 +0300 Subject: [PATCH 16/60] emergency nearest ui changes --- lib/config/localized_values.dart | 4 +- lib/pages/ErService/NearestEr.dart | 76 ++++++++++++++---------------- lib/widgets/hospital_location.dart | 19 ++++---- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index f69c3f68..6135d333 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1095,8 +1095,8 @@ const Map localizedValues = { "driveThru": {"en": "Drive-Thru", "ar": "من السيارة"}, "trackDeliveryDriver": {"en": "Track Delivery Driver", "ar": "تتبع السائق"}, "NearestErDesc": { - "en": "\nThis service Displays nearest branch\n among all the branches of All Habib \n medical Group based on your current Location", - "ar": "\nتعرض هذه الخدمة أقرب فرع\n من بين جميع فروع مجموعة \nالحبيب الطبية بناءً على موقعك الحالي." + "en": "This service Displays nearest branch among all the branches of All Habib medical Group based on your current Location", + "ar": "تعرض هذه الخدمة أقرب فرع من بين جميع فروع مجموعة الحبيب الطبية بناءً على موقعك الحالي." }, "NearestEr": {"en": "Nearest ER", "ar": "اقرب طوارئ"}, "infoCMC": { diff --git a/lib/pages/ErService/NearestEr.dart b/lib/pages/ErService/NearestEr.dart index c3c6564d..845a8fe7 100644 --- a/lib/pages/ErService/NearestEr.dart +++ b/lib/pages/ErService/NearestEr.dart @@ -1,8 +1,10 @@ +import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/model/er/projectavgerwaitingtime.dart'; import 'package:diplomaticquarterapp/core/service/er/er_service.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/hospital_location.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -25,7 +27,7 @@ class NearestEr extends StatefulWidget { class _NearestErState extends State { List projectAvgERWaitingTimeModelList = List(); - bool isDataLoaded = false; + bool isDataLoaded; @override void initState() { @@ -45,47 +47,41 @@ class _NearestErState extends State { showNewAppBarTitle: true, showNewAppBar: true, appBarTitle: TranslationBase.of(context).NearestEr, - body: isDataLoaded - ? Container( - child: ListView( - children: [ - Text(TranslationBase.of(context).NearestErDesc, - textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, letterSpacing: 1.0, fontWeight: FontWeight.w900, color: new Color(0xFF60686b))), - Container( - margin: EdgeInsets.fromLTRB(2.0, 10.0, 0.0, 10.0), - child: GridView.count( - crossAxisCount: 2, - childAspectRatio: (itemWidth / itemWidth), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - controller: new ScrollController(keepScrollOffset: false), + body: isDataLoaded != null + ? isDataLoaded + ? ListView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + children: [ + Text( + TranslationBase.of(context).NearestErDesc, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox(height: 21), + ListView.separated( + physics: NeverScrollableScrollPhysics(), shrinkWrap: true, - padding: const EdgeInsets.all(4.0), - children: List.generate(projectAvgERWaitingTimeModelList.length, (index) { - return Container( - child: CardPosition( - waitingTime: projectAvgERWaitingTimeModelList[index].avgTimeInHHMM.toString(), - text: projectAvgERWaitingTimeModelList[index].projectName.toString(), - image: 'assets/images/new-design/find_us_icon.png', - subText: projectAvgERWaitingTimeModelList[index].distanceInKilometers.toString() + " " + TranslationBase.of(context).km, - type: projectAvgERWaitingTimeModelList[index].iD.toString(), - telephone: projectAvgERWaitingTimeModelList[index].phoneNumber.toString(), - networkImage: projectAvgERWaitingTimeModelList[index].projectImageURL.toString(), - latitude: projectAvgERWaitingTimeModelList[index].latitude, - longitude: projectAvgERWaitingTimeModelList[index].longitude, - projectname: projectAvgERWaitingTimeModelList[index].projectName, - cardSize: itemWidth, - ), - ); - }), + padding: EdgeInsets.zero, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) { + GetHMGLocationsModel location = GetHMGLocationsModel(); + location.locationName = projectAvgERWaitingTimeModelList[index].projectName; + location.cityName = projectAvgERWaitingTimeModelList[index].projectName; + location.projectImageURL = projectAvgERWaitingTimeModelList[index].projectImageURL; + location.phoneNumber = projectAvgERWaitingTimeModelList[index].phoneNumber; + location.latitude = projectAvgERWaitingTimeModelList[index].latitude; + location.longitude = projectAvgERWaitingTimeModelList[index].longitude; + location.distanceInKilometers = projectAvgERWaitingTimeModelList[index].distanceInKilometers; + return HospitalLocation(location, waitingTime: projectAvgERWaitingTimeModelList[index].avgTimeInHHMM.toString()); + }, + itemCount: projectAvgERWaitingTimeModelList.length, ), - ), - ], - ), - ) - : Center( - child: Texts('No Data'), - ), + ], + ) + : Center( + child: Texts('No Data'), + ) + : SizedBox(), ); } diff --git a/lib/widgets/hospital_location.dart b/lib/widgets/hospital_location.dart index dd70d06f..30aad0a0 100644 --- a/lib/widgets/hospital_location.dart +++ b/lib/widgets/hospital_location.dart @@ -6,13 +6,15 @@ import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'avatar/large_avatar.dart'; import 'my_rich_text.dart'; class HospitalLocation extends StatelessWidget { final GetHMGLocationsModel location; final bool showCity; + final String waitingTime; - HospitalLocation(this.location, {Key key, this.showCity = false}) : super(key: key); + HospitalLocation(this.location, {Key key, this.showCity = false, this.waitingTime}) : super(key: key); @override Widget build(BuildContext context) { @@ -46,14 +48,12 @@ class HospitalLocation extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ClipRRect( - borderRadius: BorderRadius.circular(30), - child: Image.network( - location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg', - width: 48, - height: 48, - fit: BoxFit.cover, - ), + LargeAvatar( + name: "", + url: location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg', + width: 48, + height: 48, + radius: 30, ), SizedBox(width: 10), Expanded( @@ -62,6 +62,7 @@ class HospitalLocation extends StatelessWidget { children: [ if (showCity) MyRichText(TranslationBase.of(context).city + ":", location.cityName?.trim().toString(), projectViewModel.isArabic), MyRichText(TranslationBase.of(context).distance + ":", location.distanceInKilometers.toString() + " " + TranslationBase.of(context).km_ ?? "", projectViewModel.isArabic), + if (waitingTime != null) MyRichText(TranslationBase.of(context).waitingTime, waitingTime, projectViewModel.isArabic), ], ), ) From de43c6bfa411485c282a75d6b1e9a952428b107c Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 25 Oct 2021 17:19:21 +0300 Subject: [PATCH 17/60] improvements --- lib/widgets/hospital_location.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/widgets/hospital_location.dart b/lib/widgets/hospital_location.dart index 7cde4f5a..401d62ef 100644 --- a/lib/widgets/hospital_location.dart +++ b/lib/widgets/hospital_location.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/show_zoom_image_dialog.dart'; import 'package:flutter/material.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; @@ -52,7 +50,7 @@ class HospitalLocation extends StatelessWidget { children: [ LargeAvatar( name: "", - url: location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg', + url: location?.projectImageURL?.toString() ?? 'https://hmgwebservices.com/Images/Hospitals/15.jpg', width: 48, height: 48, radius: 30, From 30c6f1dedb1796d6d7fe2fcc3da6951307042cd6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 25 Oct 2021 17:41:23 +0300 Subject: [PATCH 18/60] Updates --- lib/config/localized_values.dart | 5 + .../all_habib_medical_service_page2.dart | 54 +++--- .../health-weather-indicator.dart | 54 +++--- .../smart_watch_instructions.dart | 172 +++++++++--------- lib/uitl/translations_delegate_base.dart | 10 + 5 files changed, 156 insertions(+), 139 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d1f138e4..113f397f 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1594,4 +1594,9 @@ const Map localizedValues = { "supportedWatches": { "en": "Supported SmartWatches", "ar": "الساعات الذكية المدعومة" }, "watchInstructions": { "en": "Watch Instructions:", "ar": "تعليمات الساعة:" }, "monthlyTab": {"en": "Monthly", "ar": "شهري"}, + "moreSupportedWatches": {"en": "More Supported Smartwatches...", "ar": "المزيد من الساعات الذكية المدعومة..."}, + "android-instructions-1": { "en": "Make sure that you have installed 'WearOS' & 'Google Fit' apps from Google PlayStore.", "ar": "تأكد من تثبيت تطبيقات 'WearOS' و 'Google Fit' من متجر Google PlayStore." }, + "android-instructions-2": { "en": "Make sure that you have installed your watch related apps from Google PlayStore.", "ar": "تأكد من أنك قمت بتثبيت التطبيقات المتعلقة بالساعات من Google PlayStore." }, + "android-instructions-3": { "en": "Make sure that your Smart Watch is connected with the WearOS app & your watch apps.", "ar": "تأكد من أن ساعتك الذكية متصلة بتطبيق WearOS وتطبيقات ساعتك." }, + "android-instructions-4": { "en": "Make sure that your smart watch apps are linked/associated with Google Fit App.", "ar": "تأكد من أن تطبيقات ساعتك الذكية مرتبطة / مرتبطة بتطبيق Google Fit." }, "android-instructions-5": { "en": "Make sure that data like heart rate, steps, distance etc. are being shown on your watch app & on Google Fit app & both are in sync.", "ar": "تأكد من عرض بيانات مثل معدل ضربات القلب والخطوات والمسافة وما إلى ذلك على تطبيق الساعة وعلى تطبيق Google Fit وكلاهما في حالة مزامنة." }, }; diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart index fc3eebb5..6b31b1ba 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; @@ -89,28 +90,25 @@ class _AllHabibMedicalSevicePage2State extends State child: SingleChildScrollView( child: Column( children: [ - AspectRatio( - aspectRatio: 1.9, - child: Container( - width: double.infinity, - height: double.infinity, - decoration: containerRadiusWithGradient(0, - color1: timeCalculator(6, 0, 10, 59) - ? Color(0xFFB3E3FE) - : timeCalculator(11, 0, 15, 59) - ? Color(0xFFFF9E7E) - : Color(0xFF2E6686), - color2: timeCalculator(6, 0, 10, 59) - ? Color(0xFF9AC7FF) - : timeCalculator(11, 0, 15, 59) - ? Color(0xFFFECB50) - : Color(0xFF122F48)), - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Stack( - alignment: projectViewModel.isArabic ? Alignment.centerLeft : Alignment.centerRight, - children: [ - Column( + Container( + width: double.infinity, + decoration: containerRadiusWithGradient(0, + color1: timeCalculator(6, 0, 10, 59) + ? Color(0xFFB3E3FE) + : timeCalculator(11, 0, 15, 59) + ? Color(0xFFFF9E7E) + : Color(0xFF2E6686), + color2: timeCalculator(6, 0, 10, 59) + ? Color(0xFF9AC7FF) + : timeCalculator(11, 0, 15, 59) + ? Color(0xFFFECB50) + : Color(0xFF122F48)), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Row( + children: [ + Expanded( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Directionality( @@ -134,7 +132,6 @@ class _AllHabibMedicalSevicePage2State extends State color: Colors.white, ), ), - mFlex(0), Text( TranslationBase.of(context).healthWeatherIndicators, style: TextStyle( @@ -172,12 +169,11 @@ class _AllHabibMedicalSevicePage2State extends State ) ], ), - Image.asset( - "assets/images/Weather_ico.png", - color: Colors.white.withOpacity(0.5), - ), - ], - ), + ), + SvgPicture.asset( + "assets/images/new/cloudy.svg", + ), + ], ), ), ), diff --git a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart index 39264fe8..d85db81f 100644 --- a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart +++ b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/weather_slider/weather_slider.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; class HealthWeatherIndicator extends StatefulWidget { @@ -49,28 +50,25 @@ class _HospitalsPageState extends State { body: mode.weatherIndicatorData.length > 0 ? SingleChildScrollView( child: Column(children: [ - AspectRatio( - aspectRatio: 2.3, - child: Container( - width: double.infinity, - height: double.infinity, - decoration: containerRadiusWithGradient(0, - color1: timeCalculator(6, 0, 10, 59) - ? Color(0xFFB3E3FE) - : timeCalculator(11, 0, 15, 59) - ? Color(0xFFFF9E7E) - : Color(0xFF2E6686), - color2: timeCalculator(6, 0, 10, 59) - ? Color(0xFF9AC7FF) - : timeCalculator(11, 0, 15, 59) - ? Color(0xFFFECB50) - : Color(0xFF122F48)), - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Stack( - alignment: projectViewModel.isArabic ? Alignment.centerLeft : Alignment.centerRight, - children: [ - Column( + Container( + width: double.infinity, + decoration: containerRadiusWithGradient(0, + color1: timeCalculator(6, 0, 10, 59) + ? Color(0xFFB3E3FE) + : timeCalculator(11, 0, 15, 59) + ? Color(0xFFFF9E7E) + : Color(0xFF2E6686), + color2: timeCalculator(6, 0, 10, 59) + ? Color(0xFF9AC7FF) + : timeCalculator(11, 0, 15, 59) + ? Color(0xFFFECB50) + : Color(0xFF122F48)), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Row( + children: [ + Expanded( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Directionality( @@ -94,7 +92,6 @@ class _HospitalsPageState extends State { color: Colors.white, ), ), - mFlex(0), Text( TranslationBase.of(context).healthWeatherIndicators, style: TextStyle( @@ -115,12 +112,11 @@ class _HospitalsPageState extends State { ), ], ), - Image.asset( - "assets/images/Weather_ico.png", - color: Colors.white.withOpacity(0.5), - ), - ], - ), + ), + SvgPicture.asset( + "assets/images/new/cloudy.svg", + ), + ], ), ), ), diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index 4c515e3a..7cc6ab01 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/health_data_list.dart'; import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchIntegrationService.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -64,7 +65,7 @@ class _SmartWatchInstructionsState extends State { // margin: EdgeInsets.only(top: 10.0), child: CarouselSlider( carouselController: buttonCarouselController, - options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.9), + options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.65), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { @@ -338,10 +339,11 @@ class _SmartWatchInstructionsState extends State { ), child: i == 1 ? Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0), - child: Text("Supported Smartwatches", style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold, fontFamily: "WorkSans")), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), ), Container( child: Row( @@ -487,124 +489,132 @@ class _SmartWatchInstructionsState extends State { launch("https://wearos.google.com/#find-your-watch"); }, child: Container( - margin: EdgeInsets.only(top: 20.0), - child: Text("More Supported Smartwatches...", style: TextStyle(fontSize: 17.0, color: Colors.blue, decoration: TextDecoration.underline)), + margin: EdgeInsets.only(top: 20.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).moreSupportedWatches, + textAlign: TextAlign.center, style: TextStyle(fontSize: 14.0, color: Colors.blue, decoration: TextDecoration.underline, letterSpacing: -0.36)), ), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "It Seems like you haven't synced your health data with the Dr. Alhabib App before. To proceed further, you need to sync your health data with the Dr. Alhabib App", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( margin: EdgeInsets.all(10.0), - child: - Text("Before syncing data, please make sure that you have followed the instructions properly", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( margin: EdgeInsets.all(15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("CONTINUE", style: TextStyle(fontSize: 18.0)), - ), + child: DefaultButton( + TranslationBase.of(context).continues, + () { + buttonCarouselController.nextPage(); + }, + color: CustomColors.green, ), ), ], ) : Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0), - child: Text("Watch Instructions:", style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold, fontFamily: "WorkSans")), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).watchInstructions, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), ), Container( margin: EdgeInsets.all(10.0), - child: Text( - "It Seems like you haven't synced your health data with the Dr. Alhabib App before. To proceed further, you need to sync your health data with the Dr. Alhabib App", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), Container( margin: EdgeInsets.all(10.0), - child: Text("Before syncing data, please make sure that following instructions are met: ", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).syncInstructionsIntro3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), Container( margin: EdgeInsets.all(10.0), - child: Text("1. Make sure that you have installed 'WearOS' & 'Google Fit' apps from Google PlayStore.", - textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).androidInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), Container( margin: EdgeInsets.all(10.0), - child: Text("2. Make sure that you have installed your watch related apps from Google PlayStore.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).androidInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), Container( margin: EdgeInsets.all(10.0), - child: - Text("3. Make sure that your Smart Watch is connected with the WearOS app & your watch apps.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).androidInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), Container( margin: EdgeInsets.all(10.0), - child: Text("4. Make sure that your smart watch apps are linked/associated with Google Fit App.", textAlign: TextAlign.center, style: TextStyle(fontSize: 17.0)), + child: Text(TranslationBase.of(context).androidInstructions4, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), ), - Container( - margin: EdgeInsets.fromLTRB(15.0, 75.0, 15.0, 15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("SYNC HEALTH DATA", style: TextStyle(fontSize: 18.0)), - ), - ), - ), - hasAlreadySynced - ? Container( - margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 15.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { + Padding( + padding: const EdgeInsets.fromLTRB(12.0, 50.0, 12.0, 20.0), + child: Row( + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).syncHealthData, + () {}, + color: Color(0xFFD02127), + disabledColor: Color(0xff28323A).withOpacity(0.3), + ), + ), + mWidth(12), + if (hasAlreadySynced) + Expanded( + child: DefaultButton( + TranslationBase.of(context).alreadySynced, + () { _openHealthDataList(); }, - child: Text("ALREADY SYNCED", style: TextStyle(fontSize: 18.0)), + color: Color(0xff359846), ), ), - ) - : Container(), + ], + ), + ), + // Container( + // margin: EdgeInsets.fromLTRB(15.0, 75.0, 15.0, 15.0), + // child: ButtonTheme( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // minWidth: MediaQuery.of(context).size.width, + // height: 45.0, + // child: RaisedButton( + // color: new Color(0xFF60686b), + // textColor: Colors.white, + // elevation: 0, + // disabledTextColor: Colors.white, + // disabledColor: new Color(0xFFbcc2c4), + // onPressed: () { + // buttonCarouselController.nextPage(); + // }, + // child: Text("SYNC HEALTH DATA", style: TextStyle(fontSize: 18.0)), + // ), + // ), + // ), + // hasAlreadySynced + // ? Container( + // margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 15.0), + // child: ButtonTheme( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // minWidth: MediaQuery.of(context).size.width, + // height: 45.0, + // child: RaisedButton( + // color: new Color(0xFF60686b), + // textColor: Colors.white, + // elevation: 0, + // disabledTextColor: Colors.white, + // disabledColor: new Color(0xFFbcc2c4), + // onPressed: () { + // _openHealthDataList(); + // }, + // child: Text("ALREADY SYNCED", style: TextStyle(fontSize: 18.0)), + // ), + // ), + // ) + // : Container(), ], ), )); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index e82c6521..c0578bbb 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2552,6 +2552,16 @@ class TranslationBase { String get watchInstructions => localizedValues["watchInstructions"][locale.languageCode]; String get monthlyTab => localizedValues["monthlyTab"][locale.languageCode]; + + String get moreSupportedWatches => localizedValues["moreSupportedWatches"][locale.languageCode]; + + String get androidInstructions1 => localizedValues["android-instructions-1"][locale.languageCode]; + + String get androidInstructions2 => localizedValues["android-instructions-2"][locale.languageCode]; + + String get androidInstructions3 => localizedValues["android-instructions-3"][locale.languageCode]; + + String get androidInstructions4 => localizedValues["android-instructions-4"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 940441106ab4b7cea3e0d4611be45f224d80a4f4 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 25 Oct 2021 18:00:21 +0300 Subject: [PATCH 19/60] UI fixes --- lib/pages/ChildVaccines/add_newchild_page.dart | 1 + lib/pages/ChildVaccines/new/child_vaccine_page.dart | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index 496488d7..84989ed3 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -77,6 +77,7 @@ class _AddNewChildPageState extends State { builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).vaccination, + showNewAppBarTitle: true, showNewAppBar: true, body: Container( child: Column( diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index 71e1ea3f..cdf4e4e6 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -137,7 +137,7 @@ class _ChildPageState extends State with SingleTickerProviderS } }, child: Container( - decoration: containerRadius(Colors.black.withOpacity(0.2), 2000), + decoration: containerRadius(Colors.grey.withOpacity(0.2), 2000), padding: EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8), child: Row( children: [ From e3bfe83ea239129ff0bb806cc35a64d49ddff013 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Tue, 26 Oct 2021 09:48:19 +0300 Subject: [PATCH 20/60] app bar back icon issue --- lib/widgets/others/app_scaffold_widget.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 735eb9af..45642833 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -197,12 +197,15 @@ class NewAppBarWidget extends StatelessWidget with PreferredSizeWidget { return AppBar( elevation: 0, backgroundColor: showTitle ? Colors.white : Colors.transparent, - automaticallyImplyLeading: false, + // automaticallyImplyLeading: false, + leading: ArrowBack( + onTap: onTap, + ), + titleSpacing: -8, + // centerTitle: false, title: Row( children: [ - ArrowBack( - onTap: onTap, - ), + if (showTitle) Expanded( child: Text( From e913316c549938b7834f88831cf19b5a9dac96a2 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 26 Oct 2021 11:54:11 +0300 Subject: [PATCH 21/60] Updates --- .../all_habib_medical_service_page2.dart | 42 ++++++++------- .../ChildVaccines/add_newchild_page.dart | 15 ++---- .../ChildVaccines/new/child_initial_page.dart | 12 ++--- .../ChildVaccines/new/child_vaccine_page.dart | 24 +++------ .../insurance/insurance_card_screen.dart | 5 +- .../insurance_card_update_details.dart | 54 +------------------ lib/pages/insurance/insurance_page.dart | 1 + lib/pages/landing/landing_page.dart | 6 +-- lib/pages/livecare/livecare_type_select.dart | 4 +- lib/widgets/others/app_scaffold_widget.dart | 1 + 10 files changed, 47 insertions(+), 117 deletions(-) diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart index 6b31b1ba..ac4c11e1 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart @@ -150,28 +150,32 @@ class _AllHabibMedicalSevicePage2State extends State color: Colors.white, ), ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: HealthWeatherIndicator(), - ), - ); - }, - child: Padding( - padding: const EdgeInsets.only(top: 0, bottom: 0), - child: Text( - TranslationBase.of(context).moreDetails, - style: TextStyle(fontSize: 12, letterSpacing: -0.72, fontWeight: FontWeight.w600, color: Colors.white, decoration: TextDecoration.underline), - ), - ), - ) ], ), ), - SvgPicture.asset( - "assets/images/new/cloudy.svg", + Column( + children: [ + SvgPicture.asset( + "assets/images/new/cloudy.svg", + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: HealthWeatherIndicator(), + ), + ); + }, + child: Padding( + padding: const EdgeInsets.only(top: 10, bottom: 0), + child: Text( + TranslationBase.of(context).moreDetails, + style: TextStyle(fontSize: 12, letterSpacing: -0.72, fontWeight: FontWeight.w600, color: Colors.white, decoration: TextDecoration.underline), + ), + ), + ) + ], ), ], ), diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index 84989ed3..fa526360 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -4,15 +4,12 @@ import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model import 'package:diplomaticquarterapp/core/model/childvaccines/create_new_user_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/add_new_child_view_model.dart'; -import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/DayCheckBoxDialog.dart'; -import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -72,7 +69,6 @@ class _AddNewChildPageState extends State { @override Widget build(BuildContext context) { - return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, @@ -254,12 +250,9 @@ class _AddNewChildPageState extends State { width: double.infinity, padding: EdgeInsets.all(16), color: Colors.white, - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false ? Colors.white24 : CustomColors.accentColor, - label: TranslationBase.of(context).add, - // - onTap: () async { + child: DefaultButton( + TranslationBase.of(context).add, + () async { newChild.babyName = _firstTextController.text + " " + _secondTextController.text; newChild.gender = checkedValue.toString(); newChild.strDOB = getStartDay(); diff --git a/lib/pages/ChildVaccines/new/child_initial_page.dart b/lib/pages/ChildVaccines/new/child_initial_page.dart index 6069f814..a0deec0c 100644 --- a/lib/pages/ChildVaccines/new/child_initial_page.dart +++ b/lib/pages/ChildVaccines/new/child_initial_page.dart @@ -1,13 +1,12 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; -import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -126,12 +125,9 @@ class _ChildVaccinesPageState extends State with SingleTickerP }, ), if (checkedValue) mHeight(16), - SecondaryButton( - textColor: Colors.white, - color: CustomColors.accentColor, - label: TranslationBase.of(context).viewListChildren, - // - onTap: () => Navigator.push( + DefaultButton( + TranslationBase.of(context).viewListChildren, + () => Navigator.push( context, FadePage( page: ChildVaccinePage(), diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index cdf4e4e6..81f83798 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -1,13 +1,11 @@ import 'package:diplomaticquarterapp/core/model/childvaccines/delete_baby_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -56,7 +54,7 @@ class _ChildPageState extends State with SingleTickerProviderS ); }, child: Container( - margin: EdgeInsets.only(left: 16, right: 16,top: index==0?16:0,bottom: index==model.babyInformationModelList.length-1?16:0), + margin: EdgeInsets.only(left: 16, right: 16, top: index == 0 ? 16 : 0, bottom: index == model.babyInformationModelList.length - 1 ? 16 : 0), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(12)), @@ -111,7 +109,7 @@ class _ChildPageState extends State with SingleTickerProviderS color: selectedColor, ), ), - Text(DateUtil.yearMonthDay(model.babyInformationModelList[index].dOB), + Text(" " + DateUtil.getDayMonthYearDateFormatted(model.babyInformationModelList[index].dOB), style: TextStyle( fontSize: 11, color: selectedColor, @@ -175,19 +173,9 @@ class _ChildPageState extends State with SingleTickerProviderS width: double.infinity, padding: EdgeInsets.all(16), color: Colors.white, - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue - ? CustomColors.accentColor - : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: TranslationBase.of(context).addNewChild, - // - onTap: () { + child: DefaultButton( + TranslationBase.of(context).addNewChild, + () { Navigator.push( context, FadePage( diff --git a/lib/pages/insurance/insurance_card_screen.dart b/lib/pages/insurance/insurance_card_screen.dart index 9e95e0fe..b84b63d3 100644 --- a/lib/pages/insurance/insurance_card_screen.dart +++ b/lib/pages/insurance/insurance_card_screen.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_details.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -113,9 +114,7 @@ class _InsuranceCardState extends State { style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), ), Text( - convertDateFormat( - model.insurance[index].cardValidTo, - ), + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(model.insurance[index].cardValidTo)), style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), ), ], diff --git a/lib/pages/insurance/insurance_card_update_details.dart b/lib/pages/insurance/insurance_card_update_details.dart index c6eccae1..f765d9b7 100644 --- a/lib/pages/insurance/insurance_card_update_details.dart +++ b/lib/pages/insurance/insurance_card_update_details.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -344,59 +345,6 @@ class InsuranceCardUpdateDetails extends StatelessWidget { ), ], ), - // bottomSheet: Container( - // width: double.infinity, - // height: insuranceCardDetailsModel.isEmpty ? MediaQuery.of(context).size.height * 0.14 : MediaQuery.of(context).size.height * 0.21, - // child: Container( - // margin: EdgeInsets.only(left: 8, right: 8), - // child: Column( - // children: [ - // SizedBox( - // height: 8, - // ), - // if (insuranceCardDetailsModel.isEmpty) - // SecondaryButton( - // textColor: Colors.white, - // label: TranslationBase.of(context).scanNow.toUpperCase(), - // color: Theme.of(context).primaryColor, - // small: true, - // onTap: () async { - // confirmAttachInsuranceCardImageDialogDialog(context: context, name: name, fileNo: patientID.toString(), model: model); - // }, - // ), - // if (insuranceCardDetailsModel.isNotEmpty) - // SecondaryButton( - // textColor: Colors.white, - // label: TranslationBase.of(context).agree.toUpperCase(), - // color: Theme.of(context).primaryColor, - // onTap: () async { - // GifLoaderDialogUtils.showMyDialog(context); - // await model.uploadInsuranceCard(patientIdentificationID: patientIdentificationID, patientID: patientID); - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // AppToast.showErrorToast(message: model.error); - // } else { - // AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent); - // } - // }, - // ), - // if (insuranceCardDetailsModel.isNotEmpty) - // SizedBox( - // height: 12, - // ), - // if (insuranceCardDetailsModel.isNotEmpty) - // SecondaryButton( - // textColor: Colors.white, - // label: TranslationBase.of(context).disagree.toUpperCase(), - // color: Colors.grey[800], - // onTap: () async { - // confirmAttachInsuranceCardImageDialogDialog(context: context, name: name, fileNo: patientID.toString(), model: model); - // }, - // ) - // ], - // ), - // ), - // ), ), ); } diff --git a/lib/pages/insurance/insurance_page.dart b/lib/pages/insurance/insurance_page.dart index fb3271fd..22e1b03e 100644 --- a/lib/pages/insurance/insurance_page.dart +++ b/lib/pages/insurance/insurance_page.dart @@ -94,6 +94,7 @@ class InsurancePage extends StatelessWidget { }, child: Container( width: double.infinity, + margin: EdgeInsets.only(top: 12.0), child: Container( decoration: cardRadius(12), child: Padding( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 21160b61..9498282b 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -512,9 +512,9 @@ class _LandingPageState extends State with WidgetsBindingObserver { Widget build(BuildContext context) { projectViewModel = Provider.of(context); model = Provider.of(context); - + // currentTab == 0 ? 45 : 0.0 return Scaffold( - appBar: PreferredSize( + appBar: currentTab == 0 ? PreferredSize( preferredSize: Size.fromHeight(currentTab == 0 ? 45 : 0.0), child: AppBar( elevation: 0, @@ -598,7 +598,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { ], centerTitle: true, ), - ), + ) : null, drawer: SafeArea(child: AppDrawer()), extendBody: false, body: WillPopScope( diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index 765d6383..85bae24b 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -170,11 +170,11 @@ class _LiveCareTypeSelectState extends State { ), InkWell( onTap: (){ - // Navigator.pop(context, "schedule"); + Navigator.pop(context, "schedule"); }, child: Container( decoration: BoxDecoration( - color: Colors.grey[400], + color: Colors.grey[600], borderRadius: BorderRadius.all(Radius.circular(10.0))), height: 100.0, margin: EdgeInsets.only(top: 20.0), diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 45642833..8729fe4a 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -197,6 +197,7 @@ class NewAppBarWidget extends StatelessWidget with PreferredSizeWidget { return AppBar( elevation: 0, backgroundColor: showTitle ? Colors.white : Colors.transparent, + // backgroundColor: Colors.red, // automaticallyImplyLeading: false, leading: ArrowBack( onTap: onTap, From a4f404386b09df7f4e2010d46b79b21a31060658 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Tue, 26 Oct 2021 13:41:05 +0300 Subject: [PATCH 22/60] fixed issues --- assets/images/pharmacy_module/payment.png | Bin 0 -> 15499 bytes lib/config/localized_values.dart | 2 +- .../pharmacies/screens/cart-order-page.dart | 8 +++++--- .../product-details/footor/footer-widget.dart | 4 +++- .../screens/product-details/product-detail.dart | 15 +++++++++++++++ .../widgets/home/GridViewButtons.dart | 6 +++++- 6 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 assets/images/pharmacy_module/payment.png diff --git a/assets/images/pharmacy_module/payment.png b/assets/images/pharmacy_module/payment.png new file mode 100644 index 0000000000000000000000000000000000000000..275aa40ac7941efaafe3ec10e9a62df4aad88802 GIT binary patch literal 15499 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 { endIndent: 0, ), Image.asset( - "assets/images/pharmacy_module/payment_image.png", + "assets/images/pharmacy_module/payment.png", width: mediaQuery.size.width - 20, height: 30.0, fit: BoxFit.scaleDown, @@ -348,6 +348,7 @@ class _OrderBottomWidgetState extends State { Icons.info, size: 25, color: Color(0xff005aff), +// color: Color(0xff005aff), ), ), ), @@ -420,8 +421,9 @@ class _OrderBottomWidgetState extends State { isAgree ? Colors.white : Colors.grey.shade300, fontSize: 14), ), - color: Color(0xff005aff), - disabledColor: Color(0xff005aff), + color: Color(0xFF4CAF50), + disabledColor:Color(0xFF4CAF50), +// disabledColor: Color(0xff005aff), ) // RaisedButton( // onPressed: isAgree diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart index 3a3eba23..19286b6a 100644 --- a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -20,6 +20,7 @@ class FooterWidget extends StatefulWidget { final int quantityLimit; final PharmacyProduct item; final Function addToCartFunction; + final Function addToShoppingCartFunction; final ProductDetailViewModel model; int quantity; @@ -30,6 +31,7 @@ class FooterWidget extends StatefulWidget { {this.quantity, this.isOverQuantity = false, this.addToCartFunction, + this.addToShoppingCartFunction, this.model}); @override @@ -217,7 +219,7 @@ class _FooterWidgetState extends State { widget.quantity > widget.quantityLimit || widget.item.rxMessage != null, onTap: () async { - await widget.addToCartFunction( + await widget.addToShoppingCartFunction( quantity: widget.quantity, itemID: widget.item.id, model: widget.model); diff --git a/lib/pages/pharmacies/screens/product-details/product-detail.dart b/lib/pages/pharmacies/screens/product-details/product-detail.dart index 83a76a19..4cee4ba3 100644 --- a/lib/pages/pharmacies/screens/product-details/product-detail.dart +++ b/lib/pages/pharmacies/screens/product-details/product-detail.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/recommended_products.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart'; @@ -13,6 +14,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'availability_info.dart'; @@ -331,6 +333,7 @@ class __ProductDetailPageState extends State { quantity: quantity, isOverQuantity: isOverQuantity, addToCartFunction: addToCartFunction, + addToShoppingCartFunction: addToShoppingCartFunction, model: model, ), )); @@ -355,6 +358,18 @@ class __ProductDetailPageState extends State { await model.addToCartData(quantity, itemID); GifLoaderDialogUtils.hideDialog(context); } + + addToShoppingCartFunction( + {quantity, + itemID, + ProductDetailViewModel model}) async { + GifLoaderDialogUtils.showMyDialog(context); + await model.addToCartData(quantity, itemID); + GifLoaderDialogUtils.hideDialog(context); + Navigator.push( + context, + FadePage(page: CartOrderPage())); + } } diff --git a/lib/pages/pharmacies/widgets/home/GridViewButtons.dart b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart index 5d979136..1a33ce74 100644 --- a/lib/pages/pharmacies/widgets/home/GridViewButtons.dart +++ b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; +import 'package:diplomaticquarterapp/pages/search_products_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -44,6 +45,9 @@ class GridViewButtons extends StatelessWidget { hasColorFilter: false, child: GridViewCard(TranslationBase.of(context).medicationRefill, 'assets/images/pharmacy_module/medication_icon.png', () { + Navigator.push( + context, FadePage(page: HomePrescriptionsPage())); + // model.checkUserIsActivated().then((isActivated) { // if (isActivated) { // Navigator.push(context, FadePage(page: LakumMainPage())); @@ -71,7 +75,7 @@ class GridViewButtons extends StatelessWidget { child: GridViewCard( TranslationBase.of(context).searchAndScanMedication, 'assets/images/pharmacy_module/search_scan_icon.png', - () {}), + () {Navigator.push(context, FadePage(page: SearchProductsPage()));}), ), ], ), From 9dbe922259e2855bfd1ad058e1463a4b7fa28960 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 26 Oct 2021 14:57:10 +0300 Subject: [PATCH 23/60] pharmacy updates --- .../screens/cart-page/cart-order-page.dart | 3 +- .../shared/product_details_app_bar.dart | 65 ++++++++----------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart index 44eb3e09..5d7f10e0 100644 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart @@ -41,10 +41,9 @@ class _CartOrderPageState extends State { final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; AppScaffold appScaffold; return NetworkBaseView( - // baseViewModel: model, isLoading: isLoading, isLocalLoader: true, - child: AppScaffold( + child: appScaffold = AppScaffold( appBarTitle: TranslationBase.of(context).shoppingCart, isShowAppBar: true, isPharmacy: true, diff --git a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart index b9612925..6dc571d6 100644 --- a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -25,19 +25,9 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { final bool isInWishList; final Function addToCartFunction; + ProductAppBar({Key key, this.product, this.model, this.addToWishlistFunction, this.quantity, this.deleteFromWishlistFunction, this.isInWishList, this.addToCartFunction}) : super(key: key); - ProductAppBar( - {Key key, - this.product, - this.model, - this.addToWishlistFunction, - this.quantity, - this.deleteFromWishlistFunction, - this.isInWishList, this.addToCartFunction}) - : super(key: key); - - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); @override Widget build(BuildContext context) { @@ -75,25 +65,29 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { onPress: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => CartOrderPage()), + MaterialPageRoute(builder: (context) => CartOrderPage()), ); }), - - if(Provider.of(context, listen: false).cartResponse.quantityCount !=0) - Positioned( - top:0, right: -1.0, - child: Container( - decoration: BoxDecoration( - color: Colors.red[800], - borderRadius: BorderRadius.circular(15), - + if (Provider.of(context, listen: false).cartResponse.quantityCount != 0) + Positioned( + top: 0, + right: -1.0, + child: Container( + decoration: BoxDecoration( + color: Colors.red[800], + borderRadius: BorderRadius.circular(15), + ), + padding: EdgeInsets.only(left: 5, right: 4.5), + height: 18, + child: Center( + child: Texts( + Provider.of(context, listen: false).cartResponse.quantityCount.toString(), + style: "caption", + medium: true, + color: Colors.white, + )), ), - padding: EdgeInsets.only(left: 5, right: 4.5), - height: 18, - child: Center(child: Texts(Provider.of(context, listen: false).cartResponse.quantityCount.toString(), style: "caption", medium: true, color: Colors.white,)), - ), - ) + ) ], ), SizedBox( @@ -135,16 +129,12 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { onTap: () async { if (quantity > 0) { { - await addToCartFunction( - quantity: quantity, - itemID: itemID, - model: model); + await addToCartFunction(quantity: quantity, itemID: itemID, model: model); Navigator.of(context).pop(); } } else { - AppToast.showErrorToast( - message: "you should add quantity"); + AppToast.showErrorToast(message: "you should add quantity"); } }), ListTile( @@ -153,9 +143,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { color: !isInWishList ? Colors.white : Colors.red[800], ), title: Text( - isInWishList - ? TranslationBase.of(context).removeFromWishlist - : TranslationBase.of(context).addToWishlist, + isInWishList ? TranslationBase.of(context).removeFromWishlist : TranslationBase.of(context).addToWishlist, ), onTap: () async { if (isInWishList) @@ -170,8 +158,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { TranslationBase.of(context).compare, ), onTap: () { - Provider.of(context, listen: false) - .addItem(specificationData); + Provider.of(context, listen: false).addItem(specificationData); Navigator.of(context).pop(); }, ), From 3b4e12a5ded1ee67085d0770d1c50a8033f78c0a Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 26 Oct 2021 15:16:01 +0300 Subject: [PATCH 24/60] Layout files --- .../app/src/main/res/layout/local_video.xml | 14 +++++++++++++ .../app/src/main/res/layout/remote_video.xml | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 android/app/src/main/res/layout/local_video.xml create mode 100644 android/app/src/main/res/layout/remote_video.xml diff --git a/android/app/src/main/res/layout/local_video.xml b/android/app/src/main/res/layout/local_video.xml new file mode 100644 index 00000000..f47c48cd --- /dev/null +++ b/android/app/src/main/res/layout/local_video.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/remote_video.xml b/android/app/src/main/res/layout/remote_video.xml new file mode 100644 index 00000000..cfdbeb0d --- /dev/null +++ b/android/app/src/main/res/layout/remote_video.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file From f3462dfc193d5c7f9d4776d5c20faad2dc4a74cc Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Tue, 26 Oct 2021 17:05:02 +0300 Subject: [PATCH 25/60] Applied cost from api at cart --- android/app/build.gradle | 3 ++ .../cloud/diplomaticquarterapp/Application.kt | 26 +++++++++++++- .../diplomaticquarterapp/opentok/OpenTok.kt | 4 ++- .../app/src/main/res/layout/local_video.xml | 14 ++++++++ .../app/src/main/res/layout/remote_video.xml | 20 +++++++++++ ios/Podfile.lock | 12 +++++++ lib/config/config.dart | 14 ++++++++ .../PackagesOffersServices.dart | 7 ++-- lib/pages/landing/home_page.dart | 3 +- .../OfferAndPackagesCartPage.dart | 26 ++++++++++---- .../offers_packages/PackagesCartItemCard.dart | 34 +++++++++++-------- 11 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 android/app/src/main/res/layout/local_video.xml create mode 100644 android/app/src/main/res/layout/remote_video.xml diff --git a/android/app/build.gradle b/android/app/build.gradle index f13bce1b..25230849 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -112,5 +112,8 @@ dependencies { implementation "com.opentok.android:opentok-android-sdk:2.19.1" + compile 'com.facebook.stetho:stetho:1.5.1' + implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' + } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt index 0708653a..a9c5ea88 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt @@ -1,16 +1,40 @@ //package com.cloud.diplomaticquarterapp package com.ejada.hmg +import com.facebook.stetho.Stetho import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback -import io.flutter.plugins.GeneratedPluginRegistrant import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this) + +// Stetho.initializeWithDefaults(this); + // Create an InitializerBuilder + // Create an InitializerBuilder + val initializerBuilder = Stetho.newInitializerBuilder(this) + + + // Enable Chrome DevTools + initializerBuilder.enableWebKitInspector( + Stetho.defaultInspectorModulesProvider(this) + ) + + // Enable command line interface + initializerBuilder.enableDumpapp( + Stetho.defaultDumperPluginsProvider(this) + ) + + + // Use the InitializerBuilder to generate an Initializer + val initializer = initializerBuilder.build() + + + // Initialize Stetho with the Initializer + Stetho.initialize(initializer) } override fun registerWith(registry: PluginRegistry) { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt index 0cdc3751..d53d6f9a 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt @@ -5,8 +5,10 @@ import android.os.Handler import android.os.Looper import android.util.Log import android.view.ViewGroup +import com.facebook.stetho.urlconnection.StethoURLConnectionManager import com.opentok.android.* import io.flutter.embedding.engine.FlutterEngine +import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel @@ -21,7 +23,7 @@ enum class OpenTokSDKState { class OpenTok(private var context: Context, private var flutterEngine: FlutterEngine){ private lateinit var remoteVideoPlatformView: RemoteVideoPlatformView private lateinit var localVideoPlatformView: LocalVideoPlatformView - + init { remoteVideoPlatformView = RemoteVideoFactory.getViewInstance(context) flutterEngine diff --git a/android/app/src/main/res/layout/local_video.xml b/android/app/src/main/res/layout/local_video.xml new file mode 100644 index 00000000..f47c48cd --- /dev/null +++ b/android/app/src/main/res/layout/local_video.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/remote_video.xml b/android/app/src/main/res/layout/remote_video.xml new file mode 100644 index 00000000..cfdbeb0d --- /dev/null +++ b/android/app/src/main/res/layout/remote_video.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 549f5592..565b2db9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -450,6 +450,10 @@ PODS: - TOCropViewController (~> 2.5.4) - image_picker (0.0.1): - Flutter + - in_app_review (0.2.0): + - Flutter + - in_app_update (0.0.1): + - Flutter - just_audio (0.0.1): - Flutter - leveldb-library (1.22) @@ -579,6 +583,8 @@ DEPENDENCIES: - huawei_map (from `.symlinks/plugins/huawei_map/ios`) - image_cropper (from `.symlinks/plugins/image_cropper/ios`) - image_picker (from `.symlinks/plugins/image_picker/ios`) + - in_app_review (from `.symlinks/plugins/in_app_review/ios`) + - in_app_update (from `.symlinks/plugins/in_app_update/ios`) - just_audio (from `.symlinks/plugins/just_audio/ios`) - local_auth (from `.symlinks/plugins/local_auth/ios`) - location (from `.symlinks/plugins/location/ios`) @@ -719,6 +725,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/image_cropper/ios" image_picker: :path: ".symlinks/plugins/image_picker/ios" + in_app_review: + :path: ".symlinks/plugins/in_app_review/ios" + in_app_update: + :path: ".symlinks/plugins/in_app_update/ios" just_audio: :path: ".symlinks/plugins/just_audio/ios" local_auth: @@ -843,6 +853,8 @@ SPEC CHECKSUMS: huawei_map: 34fbad9c274ea78a4151487c9ebe27f1887777e7 image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4 image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 + in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541 + in_app_update: 16e877e205f4360264cb536e3a6481f0d90299e1 just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7 Libyuv: 5f79ced0ee66e60a612ca97de1e6ccacd187a437 diff --git a/lib/config/config.dart b/lib/config/config.dart index c1622769..37450066 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -102,6 +102,18 @@ const GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID = 'Services/Patients.svc/REST/Patient const UPDATE_PRESS_ORDER = 'Services/Patients.svc/REST/PatientER_UpdatePresOrder'; const INSERT_ER_INERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; +// HHC RC SERVICES +const HHC_GET_ALL_SERVICES_RC = "rc/api/HHC/getallhhc"; +const ADD_HHC_ORDER_RC = "rc/api/HHC/add"; +const GET_ALL_HHC_ORDERS_RC = 'rc/api/hhc/list'; +const UPDATE_HHC_ORDER_RC = 'rc/api/hhc/update'; + + +// RRT RC SERVICES +const ADD_RRT_ORDER_RC = 'rc/api/rrt/add'; +const GET_ALL_RRT_ORDERS_RC = 'rc/api/rrt/list'; +const UPDATE_RRT_ORDER_RC = 'rc/api/rrt/update'; + /// ER RRT const GET_ALL_RC_TRANSPORTATION = 'rc/api/Transportation/getalltransportation'; const GET_ALL_TRANSPORTATIONS_RC = 'rc/api/Transportation/getalltransportation'; @@ -443,6 +455,8 @@ const ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = 'Services/PatientVarification.svc/ // CMC RC SERVICES const GET_ALL_CMC_SERVICES_RC = 'rc/api/cmc/getallcmc'; const ADD_CMC_ORDER_RC = 'rc/api/cmc/add'; +const GET_ALL_CMC_ORDERS_RC = 'rc/api/cmc/list'; +const UPDATE_CMC_ORDER_RC = 'rc/api/cmc/update'; //Pharmacy wishlist const GET_WISHLIST = "shopping_cart_items/"; diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index dbc32029..46e042a4 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -224,16 +224,17 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Shopping Cart // -------------------- - Future> cartItems({@required BuildContext context, bool showLoading = true}) async{ + Future> cartItems({@required BuildContext context, bool showLoading = true}) async{ Future errorThrow; cartItemList.clear(); _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; + Map jsonResponse; await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); - var jsonResponse = json.decode(stringResponse); + jsonResponse = json.decode(stringResponse); jsonResponse['shopping_carts'].forEach((json) { cartItemList.add(PackagesCartItemsResponseModel.fromJson(json)); }); @@ -244,7 +245,7 @@ class OffersAndPackagesServices extends BaseService { errorThrow = Future.error({"error":error, "statusCode":statusCode}); }, queryParams: null); - return errorThrow ?? cartItemList; + return errorThrow ?? jsonResponse; } Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index 07958a7d..0f010169 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -421,7 +421,8 @@ class _HomePageState extends State { padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15), child: InkWell( onTap: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage())); + final user = projectViewModel.user; + Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user))); }, child: Container( decoration: BoxDecoration( diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index 727cea23..5ef0a968 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -36,6 +36,8 @@ class _PackagesCartPageState extends State languageID = await sharedPref.getString(APP_LANGUAGE); } + double subtotal,tax, total; + @override void initState() { _agreeTerms = false; @@ -145,6 +147,9 @@ class _PackagesCartPageState extends State .catchError((error) { utils.Utils.showErrorToast(error); }); + if(response.status){ + fetchData(); + } return response.status ?? false; }, )); @@ -186,7 +191,7 @@ class _PackagesCartPageState extends State height: 0.25, color: Colors.grey[300], ), - _payNow(context, onPayNowClick: onPayNowClick) + _payNow(context, subtotal: subtotal, tax: tax, total: total, onPayNowClick: onPayNowClick) ], ), ) @@ -197,7 +202,12 @@ class _PackagesCartPageState extends State } fetchData() async { - await viewModel.service.cartItems(context: context).catchError((error) {}); + await viewModel.service.cartItems(context: context).then((value){ + subtotal = value['subtotal'] ?? 0.0; + tax = value['tax'] ?? 0.0; + total = value['total'] ?? 0.0; + }).catchError((error) {}); + setState(() {}); } @@ -335,9 +345,13 @@ Widget _termsAndCondition(BuildContext context, ); } -Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { +Widget _payNow(BuildContext context, {double subtotal, double tax, double total, @required VoidCallback onPayNowClick}) { bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); + String _subtotal = (subtotal ?? 0.0).toStringAsFixed(2); + String _tax = (tax ?? 0.0).toStringAsFixed(2); + String _total = (total ?? 0).toStringAsFixed(2); + return Padding( padding: const EdgeInsets.all(5), child: Container( @@ -350,13 +364,13 @@ Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - '${TranslationBase.of(context).subtotal}: ${'999.9'} ${TranslationBase.of(context).sar}', + '${TranslationBase.of(context).subtotal}: $_subtotal ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), Texts( - '${TranslationBase.of(context).vat}: ${'14.9'} ${TranslationBase.of(context).sar}', + '${TranslationBase.of(context).vat}: $_tax ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, @@ -370,7 +384,7 @@ Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { ), ), Texts( - '${TranslationBase.of(context).total}: 999.99 ${TranslationBase.of(context).sar}', + '${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, diff --git a/lib/widgets/offers_packages/PackagesCartItemCard.dart b/lib/widgets/offers_packages/PackagesCartItemCard.dart index c59c08cd..ddca9d90 100644 --- a/lib/widgets/offers_packages/PackagesCartItemCard.dart +++ b/lib/widgets/offers_packages/PackagesCartItemCard.dart @@ -77,16 +77,16 @@ class PackagesCartItemCardState extends State { ), ), - Positioned( - bottom: 8, - left: 10, - child: Row( - children: [ - _totalLabel(context: context), - _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), - ], - ), - ) + // Positioned( + // bottom: 8, + // left: 10, + // child: Row( + // children: [ + // _totalLabel(context: context), + // _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), + // ], + // ), + // ) ], ) ) @@ -136,15 +136,18 @@ Widget _itemName(String name) => Padding( ); -Widget _itemPrice(double price, {@required BuildContext context}) => Padding( +Widget _itemPrice(double price, {@required BuildContext context}) { + final prc = (price ?? 0.0).toStringAsFixed(2); + return Padding( padding: const EdgeInsets.all(0), child: Texts( - '${price} ${TranslationBase.of(context).sar}', + '${prc} ${TranslationBase.of(context).sar}', fontWeight: FontWeight.bold, color: Colors.green, fontSize: 15 ) ); +} // -------------------- @@ -159,16 +162,19 @@ Widget _priceSeperator() => Padding( // -------------------- // Product Price // -------------------- -Widget _itemOldPrice(double oldPrice, {@required BuildContext context}) => Padding( +Widget _itemOldPrice(double oldPrice, {@required BuildContext context}) { + final prc = (oldPrice ?? 0.0).toStringAsFixed(2); + return Padding( padding: const EdgeInsets.all(0), child: Texts( - '${oldPrice} ${TranslationBase.of(context).sar}', + '${prc} ${TranslationBase.of(context).sar}', fontWeight: FontWeight.normal, decoration: TextDecoration.lineThrough, color: Colors.grey, fontSize: 10 ) ); +} // -------------------- // Product Price From 2cff7c32466d89272fa9199306b0f488aad67403 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 26 Oct 2021 17:50:25 +0300 Subject: [PATCH 26/60] LiveCare design fixes --- lib/config/localized_values.dart | 4 +- lib/pages/ToDoList/payment_method_select.dart | 9 - lib/pages/livecare/livecare_home.dart | 22 +- lib/pages/livecare/livecare_type_select.dart | 214 ++++++------------ lib/pages/livecare/widgets/clinic_card.dart | 106 ++++----- lib/pages/livecare/widgets/clinic_list.dart | 72 +++--- lib/pages/login/confirm-login.dart | 51 +---- .../OfferAndPackagesCartPage.dart | 8 +- .../offers_packages/PackagesCartItemCard.dart | 20 +- 9 files changed, 187 insertions(+), 319 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 21ff8632..7f77d115 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1290,7 +1290,7 @@ const Map localizedValues = { "pay-options": {"en": "You can pay by the following Options:", "ar": "يمكنك الدفع عن طريق الخيارات التالية:"}, "livecare-service": {"en": "LiveCare Service", "ar": "خدمة لايف كير"}, "livecare-service-desc": {"en": "is to obtain medical advice with a specialist doctor Via a video call", "ar": "هي الحصول على استشارة طبية مع طبيب مختص عن طريق اتصال فيديو"}, - "why-livecare": {"en": "WHY LIVECARE", "ar": "لماذا خدمة اللايف كير"}, + "why-livecare": {"en": "Why LiveCare?", "ar": "?لماذا خدمة اللايف كير"}, "livecare-point-1": {"en": "No need to wait you will get Medical consultation immediately via Video call", "ar": "لا داعي للانتظار سوف تحصل على الاستشارة الطبية فورا عن طريق مكالمة الفيديو"}, "doc-virtual-appo-ins4": {"en": "The doctor will see your medical file", "ar": "سوف يتمكن الطبيب من الاطلاع على ملفك الطبي كامل"}, "doc-virtual-appo-ins5": {"en": "Free prescription delivery service", "ar": "خدمة توصيل الادوية مجانا"}, @@ -1298,7 +1298,7 @@ const Map localizedValues = { "en": "** The service is included with some insurance companies according to the terms and conditions with our best wishes for health and wellness", "ar": "** الخدمة مشمولة لدى بعض شركات التامين على حسب الشروط والاحكام مع تمنياتنا لكم بدوام الصحة والعافية" }, - "livecare-option-1": {"en": "Get Medical consultation immediately", "ar": "الحصول على الاستشارة فورا"}, + "livecare-option-1": {"en": "Get consultation immediately", "ar": "الحصول على الاستشارة فورا"}, "livecare-option-2": {"en": "Instant video call", "ar": "اتصال فيديو فوري"}, "livecare-option-3": {"en": "Book Appointment", "ar": "حجز موعد"}, "livecare-option-4": {"en": "Schedule video call", "ar": "اتصال فيديو مجدول"}, diff --git a/lib/pages/ToDoList/payment_method_select.dart b/lib/pages/ToDoList/payment_method_select.dart index ccee254b..542c1c23 100644 --- a/lib/pages/ToDoList/payment_method_select.dart +++ b/lib/pages/ToDoList/payment_method_select.dart @@ -70,15 +70,6 @@ class _PaymentMethodState extends State { padding: EdgeInsets.all(7.0), child: Image.asset("assets/images/new/payment/Mada.png"), ), - // mWidth(12), - // Text( - // "Mada", - // style: TextStyle( - // color: Colors.black, - // fontSize: 14, - // fontWeight: FontWeight.bold, - // ), - // ), mFlex(1), if (selectedPaymentMethod == "MADA") Container( diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index f91121e3..b0150c03 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -1,7 +1,5 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; -import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePendingRequest.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_list.dart'; @@ -62,7 +60,24 @@ class _LiveCareHomeState extends State with SingleTickerProviderSt body: Container( child: Column(children: [ TabBar( - labelColor: Colors.black, + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 0, bottom: 0, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), tabs: [ Tab( child: Text( @@ -87,7 +102,6 @@ class _LiveCareHomeState extends State with SingleTickerProviderSt ), ), ], - controller: _tabController, ), Expanded( child: TabBarView( diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index 85bae24b..e07c5615 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -28,188 +29,71 @@ class _LiveCareTypeSelectState extends State { showNewAppBarTitle: true, showNewAppBar: true, appBarTitle: TranslationBase.of(context).livecare.toUpperCase(), - // appBar: AppBar( - // leading: InkWell( - // onTap: () { - // Navigator.pop(context, null); - // }, - // child: Icon( - // Icons.close, - // color: Colors.white, - // ), - // ), - // title: Text(TranslationBase.of(context).bookAppo, - // style: TextStyle(color: Colors.white)), - // ), body: SingleChildScrollView( child: Container( - margin: EdgeInsets.only(left: 20.0, right: 20.0), + margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container(child: Text(TranslationBase.of(context).livecareService, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 15.0, bottom: 10.0), - child: Image.asset( - languageID == 'ar' - ? "assets/images/new-design/liveCare_ar_bg.png" - : "assets/images/new-design/liveCare_en_bg.png", - width: 120), - ), - Container( - alignment: Alignment.center, - child: Text(TranslationBase.of(context).livecareService, - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 20.0))), - Container( - margin: EdgeInsets.only(top: 0.0), - alignment: Alignment.center, - child: Text( - TranslationBase.of(context).livecareServiceDesc, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 18.0))), + margin: EdgeInsets.only(top: 7.0), + child: Text(TranslationBase.of(context).livecareServiceDesc, style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), Container( - margin: EdgeInsets.only(top: 5.0), - child: Text(TranslationBase.of(context).whyLivecare, - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 20.0))), + margin: EdgeInsets.only(top: 20.0), + child: Text(TranslationBase.of(context).whyLivecare, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), Container( - margin: EdgeInsets.only(top: 0.0, left: 20.0), child: Row( children: [ - SvgPicture.asset("assets/images/new-design/check_icon.svg", - width: 25), + SvgPicture.asset("assets/images/new-design/allow.svg", width: 20), Container( width: MediaQuery.of(context).size.width * 0.72, - margin: EdgeInsets.all(10.0), - child: Text( - TranslationBase.of(context).livecarePoint1, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 14.0)), + margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), + child: Text(TranslationBase.of(context).livecarePoint1, + overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0, letterSpacing: -0.64, color: CustomColors.black, fontWeight: FontWeight.w600)), ) ], ), ), Container( - margin: EdgeInsets.only(top: 5.0, left: 20.0), child: Row( children: [ - SvgPicture.asset("assets/images/new-design/check_icon.svg", - width: 25), + SvgPicture.asset("assets/images/new-design/allow.svg", width: 20), Container( width: MediaQuery.of(context).size.width * 0.72, - margin: EdgeInsets.all(10.0), + margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), child: Text(TranslationBase.of(context).docVirtualAppoIns4, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 14.0)), + overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0, letterSpacing: -0.64, color: CustomColors.black, fontWeight: FontWeight.w600)), ) ], ), ), Container( - margin: EdgeInsets.only(top: 5.0, left: 20.0), child: Row( children: [ - SvgPicture.asset("assets/images/new-design/check_icon.svg", - width: 25), + SvgPicture.asset("assets/images/new-design/allow.svg", width: 20), Container( width: MediaQuery.of(context).size.width * 0.72, - margin: EdgeInsets.all(10.0), + margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), child: Text(TranslationBase.of(context).docVirtualAppoIns5, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 14.0)), + overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0, letterSpacing: -0.64, color: CustomColors.black, fontWeight: FontWeight.w600)), ) ], ), ), Container( - margin: EdgeInsets.only(top: 10.0), - child: Text( - TranslationBase.of(context).livecareSummary, - style: TextStyle(fontSize: 12.0))), - InkWell( - onTap: (){ - Navigator.pop(context, "immediate"); - }, - child: Container( - decoration: BoxDecoration( - color: Colors.red[900], - borderRadius: BorderRadius.all(Radius.circular(10.0))), - height: 100.0, - margin: EdgeInsets.only(top: 20.0), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 10.0, right: 10.0), - child: SvgPicture.asset( - "assets/images/new-design/liveCare_logo_icon_white.svg", - width: 80), - ), - Container( - width: MediaQuery.of(context).size.width * 0.56, - margin: EdgeInsets.fromLTRB(30.0, 10.0, 0.0, 0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(TranslationBase.of(context).livecareOption1, - overflow: TextOverflow.clip, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18.0, - color: Colors.white)), - Container( - margin: EdgeInsets.only(top: 0.0), - child: Text(TranslationBase.of(context).livecareOption2, textAlign: TextAlign.start, - style: TextStyle( - fontSize: 18.0, color: Colors.white)), - ) - ], - ), - ), - ], - )), - ), - InkWell( - onTap: (){ - Navigator.pop(context, "schedule"); - }, - child: Container( - decoration: BoxDecoration( - color: Colors.grey[600], - borderRadius: BorderRadius.all(Radius.circular(10.0))), - height: 100.0, - margin: EdgeInsets.only(top: 20.0), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 10.0, right: 10.0), - child: Image.asset( - "assets/images/new-design/calendar.png", - width: 60), - ), - Container( - width: MediaQuery.of(context).size.width * 0.53, - margin: EdgeInsets.fromLTRB(30.0, 10.0, 0.0, 0.0), - child: Column( - children: [ - Container( - child: Text(TranslationBase.of(context).livecareOption3, - overflow: TextOverflow.clip, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18.0, - color: Colors.white)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).livecareOption4, - style: TextStyle( - fontSize: 18.0, color: Colors.white)), - ) - ], - ), - ), - ], - )), + margin: EdgeInsets.only(top: 20.0), + child: Text(TranslationBase.of(context).livecareSummary, style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 40.0), + shrinkWrap: true, + children: [ + _loginOptionButton(TranslationBase.of(context).livecareOption1, 'assets/images/new/Live_Care.svg', 1), + _loginOptionButton(TranslationBase.of(context).livecareOption4, 'assets/images/new/book appointment.svg', 2), + ], ), SizedBox( height: 40.0, @@ -221,6 +105,44 @@ class _LiveCareTypeSelectState extends State { ); } + Widget _loginOptionButton(String _title, String _icon, int _loginIndex) { + return InkWell( + onTap: () { + if (_loginIndex == 1) { + Navigator.pop(context, "immediate"); + } else { + Navigator.pop(context, "schedule"); + } + }, + child: Container( + padding: EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + _icon, + height: _loginIndex == 1 ? 60 : 50, + width: _loginIndex == 1 ? 60 : 50, + ), + Text( + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), + ), + ], + ), + ), + ); + } + getLanguageID() async { var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); setState(() { diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index 6a7573d7..49337ee4 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; @@ -14,11 +15,7 @@ class ClinicCard extends StatefulWidget { var languageID; int isOnline; - ClinicCard( - {this.isSelected, - this.languageID, - this.isOnline, - @required this.patientERGetClinicsList}); + ClinicCard({this.isSelected, this.languageID, this.isOnline, @required this.patientERGetClinicsList}); @override _State createState() => _State(); @@ -35,90 +32,69 @@ class _State extends State { @override Widget build(BuildContext context) { - return Row( - children: [ - Card( - margin: EdgeInsets.fromLTRB(15.0, 10.0, 8.0, 8.0), - color: widget.isSelected ? Color(0xff06b806) : widget.patientERGetClinicsList.isOnline == 1 ? Colors.white : Colors.grey, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + return Container( + width: double.infinity, + margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 8.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - child: Container( - width: MediaQuery.of(context).size.width * 0.75, - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ + border: Border.all(width: 2, color: widget.isSelected ? CustomColors.green : Color(0xffEFEFEF)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Container( + padding: EdgeInsets.fromLTRB(12.0, 25.0, 12.0, 25.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Text(widget.languageID == 'ar' ? widget.patientERGetClinicsList.serviceNameN : widget.patientERGetClinicsList.serviceName, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16)), + ), + Row( + children: [ Container( - child: Text( - widget.languageID == 'ar' - ? widget.patientERGetClinicsList.serviceNameN - : widget.patientERGetClinicsList.serviceName, - style: TextStyle( - fontSize: 16.0, - color: - widget.isSelected ? Colors.white : Colors.black)), + child: Text(".", style: TextStyle(fontSize: 30.0)), + ), + Container( + child: Text("Online"), ), ], ), - ), - ), - InkWell( - onTap: () { - getClinicTimings(widget.patientERGetClinicsList); - }, - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: Container( - padding: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Icon(Icons.access_time, size: 26.0, color: Colors.red[800]), - ], - ), - ), - ), + ], ), - ], + ), ); } getClinicTimings(PatientERGetClinicsList patientERGetClinicsList) { LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service - .getLivecareClinicTiming(patientERGetClinicsList.serviceID, context) - .then((res) { + service.getLivecareClinicTiming(patientERGetClinicsList.serviceID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { - clinicsServiceTimingsResponse = - ClinicsServiceTimingsResponse.fromJson(res); - print(clinicsServiceTimingsResponse - .patientERGetClinicsServiceTimingsList.length); + clinicsServiceTimingsResponse = ClinicsServiceTimingsResponse.fromJson(res); + print(clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList.length); showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), transitionBuilder: (context, a1, a2, widget) { - final curvedValue = - Curves.easeInOutBack.transform(a1.value) - 1.0; + final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; return Transform( - transform: - Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), child: Opacity( opacity: a1.value, child: ClinicTimingsDialog( clinicName: patientERGetClinicsList.serviceName, - patientERGetClinicsServiceTimingsList: - clinicsServiceTimingsResponse - .patientERGetClinicsServiceTimingsList, + patientERGetClinicsServiceTimingsList: clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList, ), ), ); diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index afb41ea2..9a463150 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -76,11 +76,8 @@ class _clinic_listState extends State { if (LiveCareHome.isLiveCareTypeSelected != true) { openLiveCareSelectionDialog(); } else { - print("LiveCare Type Selected"); setState(() { currentSelectedLiveCareType = "immediate"; - // isDataLoaded = true; - // print(liveCareOnlineClinicsListResponse.length); getLiveCareClinicsList(); }); } @@ -440,33 +437,35 @@ class _clinic_listState extends State { isDataLoaded ? Container( height: MediaQuery.of(context).size.height * 0.7, - child: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length > 0 ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - updateSelectedScheduleIndex(liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index]); - }, - child: ScheduleClinicCard( - isSelected: selectedClinicID == liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index].serviceID ? true : false, - clinicsHaveScheduleList: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index], - languageID: languageID, + child: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length > 0 + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + updateSelectedScheduleIndex(liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index]); + }, + child: ScheduleClinicCard( + isSelected: selectedClinicID == liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index].serviceID ? true : false, + clinicsHaveScheduleList: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index], + languageID: languageID, + ), + ); + }, ), - ); - }, - ), - Container( - height: 10.0, - ), - ], - ): getNoDataWidget(context), + Container( + height: 10.0, + ), + ], + ) + : getNoDataWidget(context), ) : Container(), isDataLoaded @@ -509,16 +508,11 @@ class _clinic_listState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - margin: EdgeInsets.all(15.0), - child: Text(TranslationBase.of(context).onlineClinics, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - // itemCount: liveCareClinicsListResponse.patientERGetClinicsList.length, + padding: const EdgeInsets.only(top: 16.0), itemCount: liveCareOnlineClinicsListResponse.length, itemBuilder: (context, index) { return InkWell( @@ -533,10 +527,10 @@ class _clinic_listState extends State { ); }, ), - Container( - margin: EdgeInsets.all(15.0), - child: Text(TranslationBase.of(context).offlineClinics, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), + // Container( + // margin: EdgeInsets.all(15.0), + // child: Text(TranslationBase.of(context).offlineClinics, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + // ), ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 08df2e6c..1903e561 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; @@ -12,6 +13,7 @@ import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authent import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/Authentication/send_activation_request.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/login/register_new.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -21,6 +23,7 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -34,13 +37,12 @@ import 'package:intl/intl.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/pages/login/register_new.dart'; class ConfirmLogin extends StatefulWidget { final Function changePageViewIndex; + const ConfirmLogin({Key key, this.changePageViewIndex}) : super(key: key); + @override _ConfirmLogin createState() => _ConfirmLogin(); } @@ -640,15 +642,14 @@ class _ConfirmLogin extends State { if (result.isNeedUserAgreement == true) { //move to agreement page. } else { - insertIMEI(); + goToHome(); } } insertIMEI() { - authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) { + authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { print(err); }); - // authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {}); } getToDoCount() { @@ -670,7 +671,7 @@ class _ConfirmLogin extends State { projectViewModel.user = authenticatedUserObject.user; await authenticatedUserObject.getUser(getUser: true); - getToDoCount(); + // getToDoCount(); appointmentRateViewModel .getIsLastAppointmentRatedList() @@ -694,13 +695,12 @@ class _ConfirmLogin extends State { page: LandingPage(), ), (r) => false) - } + }, + insertIMEI() }) .catchError((err) { print(err); - //GifLoaderDialogUtils.hideDialog(context); }); - // SMSOTP.showLoadingDialog(context, false), } loading(flag) { @@ -752,37 +752,6 @@ class _ConfirmLogin extends State { ), ), ); - - // return InkWell( - // onTap: () { - // if (_flag == 0) { - // setState(() { - // isMoreOption = true; - // }); - // } else { - // authenticateUser(4, isActive: _loginIndex); - // } - // }, - // child: RoundedContainer( - // height: 150, - // borderColor: Colors.grey, - // showBorder: true, - // child: Padding( - // padding: EdgeInsets.fromLTRB(30, 15, 30, 15), - // child: Column( - // children: [ - // Image.asset( - // _icon, - // height: SizeConfig.imageSizeMultiplier * 13, - // width: SizeConfig.imageSizeMultiplier * 16, - // ), - // SizedBox( - // height: 20, - // ), - // Texts(_title, fontSize: SizeConfig.textMultiplier * 2, color: Colors.black) - // ], - // ), - // ))); } // todo 'sikander' optimize this after knowing usage diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index 727cea23..286d7501 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -8,6 +8,7 @@ import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompleted import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; @@ -170,9 +171,10 @@ class _PackagesCartPageState extends State width: 100, color: Colors.grey[300], ), - _paymentOptions(context, (paymentMethod) { - setState(() => _selectedPaymentMethod = paymentMethod); - }), + Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0), + child: getPaymentMethods(), + ), Container( height: 0.25, color: Colors.grey[300], diff --git a/lib/widgets/offers_packages/PackagesCartItemCard.dart b/lib/widgets/offers_packages/PackagesCartItemCard.dart index c59c08cd..9a0a5252 100644 --- a/lib/widgets/offers_packages/PackagesCartItemCard.dart +++ b/lib/widgets/offers_packages/PackagesCartItemCard.dart @@ -77,16 +77,16 @@ class PackagesCartItemCardState extends State { ), ), - Positioned( - bottom: 8, - left: 10, - child: Row( - children: [ - _totalLabel(context: context), - _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), - ], - ), - ) + // Positioned( + // bottom: 8, + // left: 10, + // child: Row( + // children: [ + // _totalLabel(context: context), + // _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), + // ], + // ), + // ) ], ) ) From eed4fd25094d01a916919e4f3b6f59b017a26516 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 09:55:43 +0300 Subject: [PATCH 27/60] Pharmacy prescriptions page design --- .../pharmacyModule/PrescriptionViewModel.dart | 2 +- .../fragments/home_page_fragment2.dart | 3 +- .../widgets/home/PrescriptionsWidget.dart | 278 ++++++++---------- 3 files changed, 118 insertions(+), 165 deletions(-) diff --git a/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart b/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart index 86a320e6..420ec1fa 100644 --- a/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart @@ -14,7 +14,7 @@ class PrescriptionViewModel extends BaseViewModel { getPrescription() async { await getSavedLanguage(); - if(prescriptionsList.isNotEmpty){ + if(prescriptionsList.isEmpty){ setState(ViewState.Busy); await _prescriptionService.getPrescription(); if (_prescriptionService.hasError) { diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 7fcfecae..4714c208 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -9,6 +9,7 @@ import 'package:diplomaticquarterapp/models/gradient_color.dart'; import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/models/slider_data.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart'; import 'package:diplomaticquarterapp/pages/landing/widgets/logged_slider_view.dart'; import 'package:diplomaticquarterapp/pages/landing/widgets/services_view.dart'; import 'package:diplomaticquarterapp/pages/landing/widgets/slider_view.dart'; @@ -236,7 +237,7 @@ class _HomePageFragment2State extends State { ), FlatButton( onPressed: () { - Navigator.push(context, FadePage(page: AllHabibMedicalService())); + Navigator.push(context, FadePage(page: AllHabibMedicalSevicePage2())); }, child: Text( TranslationBase.of(context).viewAllServices, diff --git a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart index 28556679..fe8ca977 100644 --- a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart +++ b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart @@ -5,8 +5,6 @@ import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_h import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -27,30 +25,21 @@ class PrescriptionsWidget extends StatelessWidget { isLocalLoader: true, baseViewModel: model, child: Container( - height: model.prescriptionsList.length > 0 - ? MediaQuery.of(context).size.height * 0.28 - : 0, child: Column( children: [ - ViewAllHomeWidget( - TranslationBase.of(context).myPrescription, - HomePrescriptionsPage()), + ViewAllHomeWidget(TranslationBase.of(context).myPrescription, HomePrescriptionsPage()), Container( - padding: EdgeInsets.symmetric( - horizontal: 18.0, vertical: 14.0), - margin: EdgeInsets.only(left: 10), + margin: EdgeInsets.only(right: 10.0, left: 10.0), + height: MediaQuery.of(context).size.height * 0.18, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, physics: ScrollPhysics(), - // physics: NeverScrollableScrollPhysics(), itemCount: model.prescriptionsList.length, itemBuilder: (context, index) { return Container( - height: MediaQuery.of(context).size.height * 0.3, - padding: EdgeInsets.only( - bottom: 5.0, left: 5.0, right: 8.0), - margin: EdgeInsets.only(right: 10.0), + padding: EdgeInsets.only(left: 8.0, right: 8.0), + margin: EdgeInsets.only(right: 5.0, left: 5.0), decoration: BoxDecoration( border: Border.all( color: Colors.grey, @@ -59,167 +48,130 @@ class PrescriptionsWidget extends StatelessWidget { ), color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( children: [ - Row( - children: [ - Column(children: [ - Container( - padding: EdgeInsets.only( - top: 10.0, - left: 10.0, - right: 10.0, - bottom: 15.0, - ), - child: CircleAvatar( - radius: 30, - backgroundColor: - Colors.transparent, - child: Image.network( - model.prescriptionsList[index] - .doctorImageURL, - width: 60, - height: 60, - ), - ), + Column(children: [ + Container( + padding: EdgeInsets.only( + top: 10.0, + left: 10.0, + right: 10.0, + bottom: 15.0, + ), + child: CircleAvatar( + radius: 30, + backgroundColor: Colors.transparent, + child: Image.network( + model.prescriptionsList[index].doctorImageURL, + width: 60, + height: 60, ), - ]), - Column( - children: [ - Container( - margin: - EdgeInsets.only(left: 1), - padding: EdgeInsets.only( - left: 15.0, right: 15.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 4.0, - ), - color: Colors.green, - borderRadius: - BorderRadius.circular( - 30.0)), - child: Text( - model.languageID == "ar" - ? model - .prescriptionsList[ - index] - .isInOutPatientDescriptionN - .toString() - : model - .prescriptionsList[ - index] - .isInOutPatientDescription - .toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - ), - )), - Row(children: [ - Image.asset( - 'assets/images/Icon-awesome-calendar.png', - width: 30, - height: 30, - ), - Text( - DateUtil.convertStringToDate( - model - .prescriptionsList[ - index] - .appointmentDate - .toString()) - .toString() - .substring(0, 10), - style: TextStyle( - color: Colors.black, - fontSize: 15.0, - ), - ) - ]), - ], ), - ], - ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ + ), + ]), + Column( + children: [ Container( - margin: EdgeInsets.only(left: 5), - child: Row(children: [ - Text( - model.prescriptionsList[index] - .doctorTitle - .toString(), - style: TextStyle( - color: Colors.black, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - Text( - model.prescriptionsList[index] - .doctorName - .toString(), + margin: EdgeInsets.only(left: 1), + padding: EdgeInsets.only(left: 15.0, right: 15.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 4.0, + ), + color: Colors.green, + borderRadius: BorderRadius.circular(30.0)), + child: Text( + model.languageID == "ar" + ? model.prescriptionsList[index].isInOutPatientDescriptionN.toString() + : model.prescriptionsList[index].isInOutPatientDescription.toString(), style: TextStyle( - color: Colors.black, + color: Colors.white, fontSize: 15.0, - fontWeight: FontWeight.bold, ), - ), - ]), - ), - ], - ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Text( - model.prescriptionsList[index] - .clinicDescription - .toString(), + )), + Row(children: [ + Image.asset( + 'assets/images/Icon-awesome-calendar.png', + width: 30, + height: 30, + ), + Text( + DateUtil.convertStringToDate(model.prescriptionsList[index].appointmentDate.toString()).toString().substring(0, 10), style: TextStyle( - color: Colors.green, + color: Colors.black, fontSize: 15.0, -// fontWeight: FontWeight.bold, ), + ) + ]), + ], + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Row(children: [ + Text( + model.prescriptionsList[index].doctorTitle.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, ), ), - ], + Text( + model.prescriptionsList[index].doctorName.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ]), ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Align( - alignment: Alignment.topLeft, - child: RatingBar.readOnly( - initialRating: model - .prescriptionsList[index] - .actualDoctorRate - .toDouble(), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + model.prescriptionsList[index].clinicDescription.toString(), + style: TextStyle( + color: Colors.green, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( + initialRating: model.prescriptionsList[index].actualDoctorRate.toDouble(), // initialRating: productRate, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), - ) - ]), - ]), + size: 15.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + ) + ]), + ]), ); }), ), From 3dc82a0547600a506323288089dca236dfa78ab1 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 10:33:51 +0300 Subject: [PATCH 28/60] Pharmacy updates --- lib/pages/landing/landing_page_pharmcy.dart | 12 +- .../pharmacies/screens/cart-order-page.dart | 13 +- .../screens/cart-page/cart-order-page.dart | 420 ------------------ .../product-details/footor/footer-widget.dart | 55 +-- .../shared/product_details_app_bar.dart | 2 +- lib/widgets/pharmacy/product_tile.dart | 109 ++--- 6 files changed, 66 insertions(+), 545 deletions(-) delete mode 100644 lib/pages/pharmacies/screens/cart-page/cart-order-page.dart diff --git a/lib/pages/landing/landing_page_pharmcy.dart b/lib/pages/landing/landing_page_pharmcy.dart index 6ae272e2..aa6f0d1c 100644 --- a/lib/pages/landing/landing_page_pharmcy.dart +++ b/lib/pages/landing/landing_page_pharmcy.dart @@ -4,10 +4,9 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/wishlist.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/profile/profile.dart'; import 'package:diplomaticquarterapp/pages/pharmacy_categorise.dart'; import 'package:diplomaticquarterapp/pages/search_products_page.dart'; @@ -146,9 +145,7 @@ class _LandingPagePharmacyState extends State { try { String barcode = result; GifLoaderDialogUtils.showMyDialog(context); - await BaseAppClient() - .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_SKU$barcode", - onSuccess: (dynamic response, int statusCode) { + await BaseAppClient().getPharmacy("$GET_PHARMACY_PRODUCTs_BY_SKU$barcode", onSuccess: (dynamic response, int statusCode) { print(response); var product = PharmacyProduct.fromJson(response["products"][0]); GifLoaderDialogUtils.hideDialog(context); @@ -158,8 +155,7 @@ class _LandingPagePharmacyState extends State { AppToast.showErrorToast(message: "Product not found"); }); } catch (apiEx) { - AppToast.showErrorToast( - message: "Something went wrong, please try again"); + AppToast.showErrorToast(message: "Something went wrong, please try again"); } } catch (barcodeEx) {} } diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index d93c3637..f81b3ef0 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -23,10 +23,9 @@ import 'cart-page/cart-order-preview.dart'; class CartOrderPage extends StatefulWidget { + final Function(int) changeTab; - const CartOrderPage({ Key key}) - : super(key: key); - + const CartOrderPage({Key key, this.changeTab}) : super(key: key); @override _CartOrderPageState createState() => _CartOrderPageState(); @@ -50,10 +49,9 @@ class _CartOrderPageState extends State { final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; AppScaffold appScaffold; return NetworkBaseView( - // baseViewModel: model, isLoading: isLoading, isLocalLoader: true, - child: AppScaffold( + child: appScaffold = AppScaffold( appBarTitle: TranslationBase.of(context).shoppingCart, isShowAppBar: true, isPharmacy: true, @@ -297,7 +295,7 @@ class _OrderBottomWidgetState extends State { Container( height: widget.height * 0.070, color: Color(0xffe6ffe0), - padding: EdgeInsets.symmetric(horizontal: 4), + padding: EdgeInsets.only(left: 15.0, right: 15.0), child: Row( children: [ InkWell( @@ -357,7 +355,8 @@ class _OrderBottomWidgetState extends State { ), Container( height: widget.height * 0.065, - margin: EdgeInsets.symmetric(vertical: 2), + margin: EdgeInsets.only(top: 5.0, bottom: 5.0), + padding: EdgeInsets.only(left: 20.0, right: 20.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart deleted file mode 100644 index 5d7f10e0..00000000 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart +++ /dev/null @@ -1,420 +0,0 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-preview.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class CartOrderPage extends StatefulWidget { - final Function(int) changeTab; - - const CartOrderPage({Key key, this.changeTab}) : super(key: key); - - @override - _CartOrderPageState createState() => _CartOrderPageState(); -} - -class _CartOrderPageState extends State { - bool isLoading = true; - - @override - void initState() { - super.initState(); - getData(); - } - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - OrderPreviewViewModel model = Provider.of(context); - - final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; - AppScaffold appScaffold; - return NetworkBaseView( - isLoading: isLoading, - isLocalLoader: true, - child: appScaffold = AppScaffold( - appBarTitle: TranslationBase.of(context).shoppingCart, - isShowAppBar: true, - isPharmacy: true, - showHomeAppBarIcon: false, - isShowDecPage: true, - baseViewModel: model, - backButtonTab: - widget.changeTab != null ? () => widget.changeTab(0) : null, - backgroundColor: Colors.white, - body: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) - ? Container( - height: height * 0.85, - width: double.infinity, - child: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureIconButton( - TranslationBase.of(context).deleteAllItems, - Icon( - Icons.delete_outline_sharp, - color: Colors.grey.shade700, - ), - onTap: () => {model.deleteShoppingCart()}, - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Container( - child: Column( - children: [ - ...List.generate( - model.cartResponse.shoppingCarts != null - ? model.cartResponse.shoppingCarts.length - : 0, - (index) => ProductOrderItem( - model.cartResponse - .shoppingCarts[index], () { - print(model.cartResponse - .shoppingCarts[index].quantity); - model - .changeProductQuantity(model - .cartResponse - .shoppingCarts[index]) - .then((value) { - if (model.state != ViewState.Error) { - appScaffold.appBar.badgeUpdater( - '${value.quantityCount ?? 0}'); - } - if (model.state == - ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } - }); - }, () { - model - .deleteProduct(model.cartResponse - .shoppingCarts[index]) - .then((value) { - if (model.state != ViewState.Error) { - appScaffold.appBar.badgeUpdater( - '${value.quantityCount ?? 0}'); - } - }); - })) - ], - ), - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 2, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).subtotal, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).vat}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotalVatAmount).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).total, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Image.asset( - "assets/images/pharmacy_module/payment_image.png", - width: mediaQuery.size.width - 20, - height: 30.0, - fit: BoxFit.scaleDown, - ), - SizedBox( - height: 120, - ) - ], - ), - ), - ), - ) - : Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Image.asset( - 'assets/images/new-design/empty_box.png', - width: 100, - height: 100, - fit: BoxFit.cover, - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - TranslationBase.of(context).noData, -// 'There is no data', - style: TextStyle(fontSize: 30), - ), - ) - ], - ), - ), - bottomSheet: Container( - height: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) - ? height * 0.15 - : 0, - color: Colors.white, - child: OrderBottomWidget(model.addresses, height), - ), - ), - ); - } - - void getData() async { - await Provider.of(context, listen: false) - .getShoppingCart(); - setState(() { - isLoading = false; - }); - } -} - -class OrderBottomWidget extends StatefulWidget { - final List addresses; - final double height; - - OrderBottomWidget(this.addresses, this.height); - - @override - _OrderBottomWidgetState createState() => _OrderBottomWidgetState(); -} - -class _OrderBottomWidgetState extends State { - bool isAgree = false; - - @override - Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); - OrderPreviewViewModel cart = Provider.of(context); - return !(cart.cartResponse.shoppingCarts == null || - cart.cartResponse.shoppingCarts.length == 0) - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Divider( - color: Color(0xFFD6D6D6), - height: 1, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Container( - height: widget.height * 0.070, - color: Color(0xffe6ffe0), - padding: EdgeInsets.symmetric(horizontal: 4), - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - isAgree = !isAgree; - }); - }, - child: Container( - width: 25.0, - height: widget.height * 0.070, - decoration: new BoxDecoration( - color: !isAgree ? Color(0xffeeeeee) : Colors.green, - shape: BoxShape.circle, - ), - child: !isAgree - ? null - : Padding( - padding: const EdgeInsets.all(0.0), - child: Icon( - Icons.check, - color: Colors.white, - size: 25, - ), - ), - ), - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 4), - margin: const EdgeInsets.symmetric(vertical: 4), - child: Texts( - TranslationBase.of(context) - .pharmacyServiceTermsCondition, - fontSize: 13, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ), - InkWell( - onTap: () => { - Navigator.push( - context, FadePage(page: PharmacyTermsConditions())) - }, - child: Container( - child: Icon( - Icons.info, - size: 25, - color: Color(0xff005aff), - ), - ), - ), - ], - ), - ), - Container( - height: widget.height * 0.065, - margin: EdgeInsets.symmetric(vertical: 2), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 0, vertical: 0), - child: Row( - children: [ - Texts( - "${TranslationBase.of(context).sar} ${(cart.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: projectProvider.isArabic ? 12 : 14, - fontWeight: FontWeight.bold, - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Texts( - "${TranslationBase.of(context).inclusiveVat}", - fontSize: 8, - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - Texts( - "${cart.cartResponse.quantityCount} ${TranslationBase.of(context).items}", - fontSize: 10, - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ], - ), - ), - RaisedButton( - onPressed: isAgree - ? () => { - Navigator.push( - context, - FadePage( - page: - OrderPreviewPage(widget.addresses))) - } - : null, - child: new Text( - "${TranslationBase.of(context).checkOut}", - style: new TextStyle( - color: - isAgree ? Colors.white : Colors.grey.shade300, - fontSize: 14), - ), - elevation: 0, - color: Color(0xff005aff), - disabledColor: Color(0xff005aff), - ), - ], - ), - ), - ], - ) - : Container(); - } -} diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart index 19286b6a..ca8222ac 100644 --- a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; @@ -10,8 +11,6 @@ import 'package:hexcolor/hexcolor.dart'; import '../../../../../locator.dart'; import '../../../../../routes.dart'; -import '../../cart-page/cart-order-page.dart'; -import '../product-detail.dart'; class FooterWidget extends StatefulWidget { final bool isAvailable; @@ -26,13 +25,8 @@ class FooterWidget extends StatefulWidget { int quantity; bool isOverQuantity; - FooterWidget(this.isAvailable, this.maxQuantity, this.minQuantity, - this.quantityLimit, this.item, - {this.quantity, - this.isOverQuantity = false, - this.addToCartFunction, - this.addToShoppingCartFunction, - this.model}); + FooterWidget(this.isAvailable, this.maxQuantity, this.minQuantity, this.quantityLimit, this.item, + {this.quantity, this.isOverQuantity = false, this.addToCartFunction, this.addToShoppingCartFunction, this.model}); @override _FooterWidgetState createState() => _FooterWidgetState(); @@ -41,8 +35,7 @@ class FooterWidget extends StatefulWidget { class _FooterWidgetState extends State { double quantityUI = 80; bool showUI = false; - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); @override Widget build(BuildContext context) { @@ -77,8 +70,7 @@ class _FooterWidgetState extends State { padding: const EdgeInsets.all(8.0), child: Text( "Quantity", - style: TextStyle( - fontSize: 15, fontWeight: FontWeight.bold), + style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), ), ), InkWell( @@ -101,11 +93,7 @@ class _FooterWidgetState extends State { SizedBox( width: 5, ), - for (int i = 1; i <= 10; i++) - QuantityBox( - label: i, - onTapFunc: onChangeValue, - isSelected: widget.quantity == i), + for (int i = 1; i <= 10; i++) QuantityBox(label: i, onTapFunc: onChangeValue, isSelected: widget.quantity == i), Container( width: 100, decoration: BoxDecoration( @@ -113,16 +101,14 @@ class _FooterWidgetState extends State { color: Colors.white, ), child: TextField( - decoration: InputDecoration( - labelText: ' Quantity # '), + decoration: InputDecoration(labelText: ' Quantity # '), onChanged: (text) { if (int.tryParse(text) == null) { text = ''; } else { setState(() { widget.quantity = int.parse(text); - if (widget.quantity >= - widget.quantityLimit) { + if (widget.quantity >= widget.quantityLimit) { widget.isOverQuantity = true; } else { widget.isOverQuantity = false; @@ -187,20 +173,14 @@ class _FooterWidgetState extends State { width: MediaQuery.of(context).size.width * 0.45, child: SecondaryButton( label: TranslationBase.of(context).addToCart.toUpperCase(), - disabled: !widget.isAvailable && widget.quantity == 0 || - widget.quantity > widget.quantityLimit || - widget.item.rxMessage != null, - disableColor: Color(0xFF4CAF50), + disabled: (!widget.isAvailable && widget.quantity > 0) || widget.quantity > widget.quantityLimit || widget.item.isRx, onTap: () async { if (!authenticatedUserObject.isLogin) { Navigator.of(context).pushNamed( WELCOME_LOGIN, ); } else - await widget.addToCartFunction( - quantity: widget.quantity, - itemID: widget.item.id, - model: widget.model); + await widget.addToCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); }, fontWeight: FontWeight.w600, borderColor: Color(0xFF4CAF50), @@ -215,14 +195,9 @@ class _FooterWidgetState extends State { width: MediaQuery.of(context).size.width * 0.35, child: SecondaryButton( label: TranslationBase.of(context).buyNow.toUpperCase(), - disabled: !widget.isAvailable && widget.quantity > 0 || - widget.quantity > widget.quantityLimit || - widget.item.rxMessage != null, + disabled: (!widget.isAvailable && widget.quantity > 0) || (widget.quantity > widget.quantityLimit) || widget.item.isRx, onTap: () async { - await widget.addToShoppingCartFunction( - quantity: widget.quantity, - itemID: widget.item.id, - model: widget.model); + await widget.addToShoppingCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); Navigator.push( context, FadePage(page: CartOrderPage()), @@ -232,11 +207,7 @@ class _FooterWidgetState extends State { borderColor: Colors.grey[800], borderRadius: 3, disableColor: Colors.grey[700], - color: !widget.isAvailable && widget.quantity > 0 || - widget.quantity > widget.quantityLimit || - widget.item.rxMessage != null - ? Colors.grey - : Colors.grey[800], + color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || widget.item.rxMessage != null ? Colors.grey : Colors.grey[800], ), ), ], diff --git a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart index 6dc571d6..a9e2a66c 100644 --- a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -12,7 +13,6 @@ import 'package:provider/provider.dart'; import '../../../../../locator.dart'; import '../../../compare-list.dart'; -import '../../cart-page/cart-order-page.dart'; import 'icon_with_bg.dart'; class ProductAppBar extends StatelessWidget with PreferredSizeWidget { diff --git a/lib/widgets/pharmacy/product_tile.dart b/lib/widgets/pharmacy/product_tile.dart index f3654b74..1c2f87cc 100644 --- a/lib/widgets/pharmacy/product_tile.dart +++ b/lib/widgets/pharmacy/product_tile.dart @@ -1,6 +1,6 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/ProductReview.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -26,27 +26,27 @@ class productTile extends StatelessWidget { final dynamic productID; final Function onDelete; final dynamic approvedTotalReviews; -// final VoidCallback deleteWishlistItems; - productTile( - {this.productName, - this.productPrice, - this.productRate, - this.productReviews, - this.qyt, - this.totalPrice, - this.isOrderDetails = false, - this.productImage, - this.showLine = true, - this.img, - this.imgs, - this.status, - this.product, - this.productID, - this.onDelete, - this.approvedTotalReviews, +// final VoidCallback deleteWishlistItems; - }); + productTile({ + this.productName, + this.productPrice, + this.productRate, + this.productReviews, + this.qyt, + this.totalPrice, + this.isOrderDetails = false, + this.productImage, + this.showLine = true, + this.img, + this.imgs, + this.status, + this.product, + this.productID, + this.onDelete, + this.approvedTotalReviews, + }); @override Widget build(BuildContext context) { @@ -91,10 +91,7 @@ class productTile extends StatelessWidget { child: RichText( text: TextSpan( text: productName, - style: TextStyle( - color: Colors.black54, - fontSize: 15, - fontWeight: FontWeight.bold), + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), ), ), ), @@ -106,19 +103,16 @@ class productTile extends StatelessWidget { child: RichText( text: TextSpan( text: 'SAR $productPrice', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), ), ), ), ), this.isOrderDetails == false ? Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( margin: EdgeInsets.all(5), child: Align( alignment: Alignment.topLeft, @@ -134,14 +128,12 @@ class productTile extends StatelessWidget { ), ), ), - Text( '$approvedTotalReviews', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.grey, - fontSize: 13), - ), - ], - ) + Text( + '$approvedTotalReviews', + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 13), + ), + ], + ) : Container(), ], ), @@ -164,9 +156,11 @@ class productTile extends StatelessWidget { height: 50, ), IconButton( - icon: Icon(Icons.shopping_cart, + icon: Icon( + Icons.shopping_cart, size: 18, - color: Colors.blue,), + color: Colors.blue, + ), onPressed: () async { GifLoaderDialogUtils.showMyDialog(context); await addToCartFunction(1, productID); @@ -192,13 +186,8 @@ class productTile extends StatelessWidget { margin: EdgeInsets.only(bottom: 5.0), child: RichText( text: TextSpan( - text: TranslationBase.of(context).quantity + - "" + - '$qyt', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.grey, - fontSize: 13), + text: TranslationBase.of(context).quantity + "" + '$qyt', + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 13), ), ), ), @@ -224,10 +213,7 @@ class productTile extends StatelessWidget { RichText( text: TextSpan( text: ' $totalPrice SAR', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 15), + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 15), ), ), ], @@ -268,30 +254,19 @@ class productTile extends StatelessWidget { child: RichText( text: TextSpan( text: '($productReviews reviews)', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.grey, - fontSize: 13), + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 13), ), ), ), ), InkWell( onTap: () { - Navigator.push( - context, FadePage(page: ProductReviewPage(product))); + Navigator.push(context, FadePage(page: ProductReviewPage(product))); }, child: Container( - padding: - EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), + padding: EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), height: 30.0, - decoration: BoxDecoration( - border: Border.all( - color: Colors.orange, - style: BorderStyle.solid, - width: 1.0), - color: Colors.transparent, - borderRadius: BorderRadius.circular(5.0)), + decoration: BoxDecoration(border: Border.all(color: Colors.orange, style: BorderStyle.solid, width: 1.0), color: Colors.transparent, borderRadius: BorderRadius.circular(5.0)), child: Text( TranslationBase.of(context).writeReview, style: TextStyle( From 1089ce3aa39de3ae72dfb467fcb94e45cb33efd4 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Wed, 27 Oct 2021 10:34:18 +0300 Subject: [PATCH 29/60] Updates --- lib/config/config.dart | 4 +- .../pharmacies/screens/cart-order-page.dart | 52 ++++++++++--------- .../screens/cart-page/cart-order-page.dart | 18 ++++--- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index bbbacaa4..2f2e823a 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,8 +14,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +//const BASE_URL = 'https://uat.hmgwebservices.com/'; + const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index d93c3637..09c39f3d 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -22,11 +23,7 @@ import 'package:provider/provider.dart'; import 'cart-page/cart-order-preview.dart'; class CartOrderPage extends StatefulWidget { - - - const CartOrderPage({ Key key}) - : super(key: key); - + const CartOrderPage({Key key}) : super(key: key); @override _CartOrderPageState createState() => _CartOrderPageState(); @@ -39,7 +36,6 @@ class _CartOrderPageState extends State { void initState() { super.initState(); getData(); - } @override @@ -206,12 +202,13 @@ class _CartOrderPageState extends State { indent: 0, endIndent: 0, ), - Image.asset( - "assets/images/pharmacy_module/payment.png", - width: mediaQuery.size.width - 20, - height: 30.0, - fit: BoxFit.scaleDown, - ), + getPaymentMethods(), +// Image.asset( +// "assets/images/pharmacy_module/payment.png", +// width: mediaQuery.size.width - 20, +// height: 30.0, +// fit: BoxFit.scaleDown, +// ), SizedBox( height: 120, ) @@ -402,27 +399,32 @@ class _OrderBottomWidgetState extends State { onPressed: isAgree // && cart.cartResponse.shoppingCarts[1].product.stockQuantity ==0 ? () => { - if(cart.isCartItemsOutOfStock()){ - // Toast msg - AppToast.showErrorToast(message: TranslationBase.of(context).outOfStockMsg) - }else { - Navigator.push( - context, - FadePage( - page: - OrderPreviewPage(widget.addresses))) - } - } + if (cart.isCartItemsOutOfStock()) + { + // Toast msg + AppToast.showErrorToast( + message: TranslationBase.of(context) + .outOfStockMsg) + } + else + { + Navigator.push( + context, + FadePage( + page: OrderPreviewPage( + widget.addresses))) + } + } : null, child: new Text( "${TranslationBase.of(context).checkOut}", style: new TextStyle( color: - isAgree ? Colors.white : Colors.grey.shade300, + isAgree ? Colors.white : Colors.grey.shade300, fontSize: 14), ), color: Color(0xFF4CAF50), - disabledColor:Color(0xFF4CAF50), + disabledColor: Color(0xFF4CAF50), // disabledColor: Color(0xff005aff), ) // RaisedButton( diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart index 5d7f10e0..699f7054 100644 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-con import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -198,12 +199,13 @@ class _CartOrderPageState extends State { indent: 0, endIndent: 0, ), - Image.asset( - "assets/images/pharmacy_module/payment_image.png", - width: mediaQuery.size.width - 20, - height: 30.0, - fit: BoxFit.scaleDown, - ), + getPaymentMethods(), +// Image.asset( +// "assets/images/pharmacy_module/payment_image.png", +// width: mediaQuery.size.width - 20, +// height: 30.0, +// fit: BoxFit.scaleDown, +// ), SizedBox( height: 120, ) @@ -407,8 +409,8 @@ class _OrderBottomWidgetState extends State { fontSize: 14), ), elevation: 0, - color: Color(0xff005aff), - disabledColor: Color(0xff005aff), + color: Color(0xFF4CAF50), + disabledColor: Color(0xFF4CAF50), ), ], ), From 428791c7256364df288cc80539497f05e6072821 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Wed, 27 Oct 2021 11:51:26 +0300 Subject: [PATCH 30/60] fixed design --- lib/config/config.dart | 4 +- .../screens/cart-page/cart-order-page.dart | 422 ------------------ .../widgets/home/PrescriptionsWidget.dart | 2 +- 3 files changed, 3 insertions(+), 425 deletions(-) delete mode 100644 lib/pages/pharmacies/screens/cart-page/cart-order-page.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 2f2e823a..bbbacaa4 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,8 +14,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -//const BASE_URL = 'https://uat.hmgwebservices.com/'; - const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart deleted file mode 100644 index 699f7054..00000000 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart +++ /dev/null @@ -1,422 +0,0 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-preview.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class CartOrderPage extends StatefulWidget { - final Function(int) changeTab; - - const CartOrderPage({Key key, this.changeTab}) : super(key: key); - - @override - _CartOrderPageState createState() => _CartOrderPageState(); -} - -class _CartOrderPageState extends State { - bool isLoading = true; - - @override - void initState() { - super.initState(); - getData(); - } - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - OrderPreviewViewModel model = Provider.of(context); - - final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; - AppScaffold appScaffold; - return NetworkBaseView( - isLoading: isLoading, - isLocalLoader: true, - child: appScaffold = AppScaffold( - appBarTitle: TranslationBase.of(context).shoppingCart, - isShowAppBar: true, - isPharmacy: true, - showHomeAppBarIcon: false, - isShowDecPage: true, - baseViewModel: model, - backButtonTab: - widget.changeTab != null ? () => widget.changeTab(0) : null, - backgroundColor: Colors.white, - body: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) - ? Container( - height: height * 0.85, - width: double.infinity, - child: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureIconButton( - TranslationBase.of(context).deleteAllItems, - Icon( - Icons.delete_outline_sharp, - color: Colors.grey.shade700, - ), - onTap: () => {model.deleteShoppingCart()}, - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Container( - child: Column( - children: [ - ...List.generate( - model.cartResponse.shoppingCarts != null - ? model.cartResponse.shoppingCarts.length - : 0, - (index) => ProductOrderItem( - model.cartResponse - .shoppingCarts[index], () { - print(model.cartResponse - .shoppingCarts[index].quantity); - model - .changeProductQuantity(model - .cartResponse - .shoppingCarts[index]) - .then((value) { - if (model.state != ViewState.Error) { - appScaffold.appBar.badgeUpdater( - '${value.quantityCount ?? 0}'); - } - if (model.state == - ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } - }); - }, () { - model - .deleteProduct(model.cartResponse - .shoppingCarts[index]) - .then((value) { - if (model.state != ViewState.Error) { - appScaffold.appBar.badgeUpdater( - '${value.quantityCount ?? 0}'); - } - }); - })) - ], - ), - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 2, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).subtotal, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).vat}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotalVatAmount).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).total, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - getPaymentMethods(), -// Image.asset( -// "assets/images/pharmacy_module/payment_image.png", -// width: mediaQuery.size.width - 20, -// height: 30.0, -// fit: BoxFit.scaleDown, -// ), - SizedBox( - height: 120, - ) - ], - ), - ), - ), - ) - : Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Image.asset( - 'assets/images/new-design/empty_box.png', - width: 100, - height: 100, - fit: BoxFit.cover, - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - TranslationBase.of(context).noData, -// 'There is no data', - style: TextStyle(fontSize: 30), - ), - ) - ], - ), - ), - bottomSheet: Container( - height: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) - ? height * 0.15 - : 0, - color: Colors.white, - child: OrderBottomWidget(model.addresses, height), - ), - ), - ); - } - - void getData() async { - await Provider.of(context, listen: false) - .getShoppingCart(); - setState(() { - isLoading = false; - }); - } -} - -class OrderBottomWidget extends StatefulWidget { - final List addresses; - final double height; - - OrderBottomWidget(this.addresses, this.height); - - @override - _OrderBottomWidgetState createState() => _OrderBottomWidgetState(); -} - -class _OrderBottomWidgetState extends State { - bool isAgree = false; - - @override - Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); - OrderPreviewViewModel cart = Provider.of(context); - return !(cart.cartResponse.shoppingCarts == null || - cart.cartResponse.shoppingCarts.length == 0) - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Divider( - color: Color(0xFFD6D6D6), - height: 1, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Container( - height: widget.height * 0.070, - color: Color(0xffe6ffe0), - padding: EdgeInsets.symmetric(horizontal: 4), - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - isAgree = !isAgree; - }); - }, - child: Container( - width: 25.0, - height: widget.height * 0.070, - decoration: new BoxDecoration( - color: !isAgree ? Color(0xffeeeeee) : Colors.green, - shape: BoxShape.circle, - ), - child: !isAgree - ? null - : Padding( - padding: const EdgeInsets.all(0.0), - child: Icon( - Icons.check, - color: Colors.white, - size: 25, - ), - ), - ), - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 4), - margin: const EdgeInsets.symmetric(vertical: 4), - child: Texts( - TranslationBase.of(context) - .pharmacyServiceTermsCondition, - fontSize: 13, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ), - InkWell( - onTap: () => { - Navigator.push( - context, FadePage(page: PharmacyTermsConditions())) - }, - child: Container( - child: Icon( - Icons.info, - size: 25, - color: Color(0xff005aff), - ), - ), - ), - ], - ), - ), - Container( - height: widget.height * 0.065, - margin: EdgeInsets.symmetric(vertical: 2), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 0, vertical: 0), - child: Row( - children: [ - Texts( - "${TranslationBase.of(context).sar} ${(cart.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: projectProvider.isArabic ? 12 : 14, - fontWeight: FontWeight.bold, - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Texts( - "${TranslationBase.of(context).inclusiveVat}", - fontSize: 8, - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - Texts( - "${cart.cartResponse.quantityCount} ${TranslationBase.of(context).items}", - fontSize: 10, - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ], - ), - ), - RaisedButton( - onPressed: isAgree - ? () => { - Navigator.push( - context, - FadePage( - page: - OrderPreviewPage(widget.addresses))) - } - : null, - child: new Text( - "${TranslationBase.of(context).checkOut}", - style: new TextStyle( - color: - isAgree ? Colors.white : Colors.grey.shade300, - fontSize: 14), - ), - elevation: 0, - color: Color(0xFF4CAF50), - disabledColor: Color(0xFF4CAF50), - ), - ], - ), - ), - ], - ) - : Container(); - } -} diff --git a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart index fe8ca977..a2bc77e1 100644 --- a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart +++ b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart @@ -30,7 +30,7 @@ class PrescriptionsWidget extends StatelessWidget { ViewAllHomeWidget(TranslationBase.of(context).myPrescription, HomePrescriptionsPage()), Container( margin: EdgeInsets.only(right: 10.0, left: 10.0), - height: MediaQuery.of(context).size.height * 0.18, + height: MediaQuery.of(context).size.height * 0.20, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, From 4858f8883af76495f9bc7662de21726c9a958a9f Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 27 Oct 2021 12:34:52 +0300 Subject: [PATCH 31/60] blood donation dialog change & improvements. --- .../orders_log_details_page.dart | 30 -- .../new_Home_health_care_step_one_page.dart | 95 ++-- .../new_home_health_care_page.dart | 427 ++++++++-------- .../orders_log_details_page.dart | 21 - .../h2o/Dialog/confirm_add_amount_dialog.dart | 104 ---- .../h2o/Dialog/select_amount_dialog.dart | 166 ------ .../h2o/add_custom_amount.dart | 133 ----- .../h2o/h20_setting.dart | 421 ++++++++-------- .../AlHabibMedicalService/h2o/today_page.dart | 4 - .../widgets/h20_floating_action_button.dart | 201 -------- lib/pages/Blood/blood_donation.dart | 476 +++++++----------- .../EdOnline/ConfirmExitPageDialog.dart | 76 --- .../ErService/EdOnline/DdServicesPage.dart | 19 - lib/pages/feedback/send_feedback_page.dart | 273 +--------- lib/pages/landing/landing_page.dart | 7 - .../medical/ask_doctor/ask_doctor_page.dart | 9 - .../my_trackers/Weight/AddWeightPage.dart | 24 - lib/widgets/buttons/defaultButton.dart | 4 + .../dialogs/radio_selection_dialog.dart | 66 +-- lib/widgets/otp/sms-popup.dart | 28 -- 20 files changed, 694 insertions(+), 1890 deletions(-) delete mode 100644 lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart delete mode 100644 lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart delete mode 100644 lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart delete mode 100644 lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart delete mode 100644 lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart index a7c12e2d..75b158b3 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart @@ -51,36 +51,6 @@ class OrdersLogDetailsPage extends StatelessWidget { }, )); return; - - // todo 'sikander' remove useless code - showDialog( - context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3); - Future.delayed(new Duration(milliseconds: 300)).then((value) async { - GifLoaderDialogUtils.showMyDialog(context); - await model.updateCmcPresOrder(updatePresOrderRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - GifLoaderDialogUtils.hideDialog(context); - } else { - AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); - await model.getCmcAllPresOrders(); - GifLoaderDialogUtils.hideDialog(context); - } - }); - // await model.updateCmcPresOrder(updatePresOrderRequestModel); - // if (model.state == ViewState.ErrorLocal) { - // Utils.showErrorToast(model.error); - // } else { - // AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); - // await model.getCmcAllPresOrders(); - // } - }, - ), - ); } return AppScaffold( diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart index 9797c384..f8e377b7 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart @@ -44,57 +44,58 @@ class _NewHomeHealthCareStepOnePageState extends State Divider( - height: 1, - color: Color(0xffE5E5E5), - ), - itemCount: widget.model.hhcAllServicesList.length), + ], + ), + ); + }, + separatorBuilder: (context, index) => Divider( + height: 1, + color: Color(0xffE5E5E5), + ), + itemCount: widget.model.hhcAllServicesList.length), + ), Container( color: Colors.white, - padding: EdgeInsets.only(top: 0, bottom: 16, right: 21, left: 21), - margin: EdgeInsets.only(top: 50.0), + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: DefaultButton( TranslationBase.of(context).next, (this.widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList.length == 0 || widget.model.state == ViewState.BusyLocal) diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart index 4a2234c6..e17558cb 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart @@ -89,236 +89,219 @@ class _NewHomeHealthCarePageState extends State with Tick ProjectViewModel projectViewModel = Provider.of(context); - return Scaffold( - body: SafeArea( - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.8, - child: Column( - children: [ - Expanded( - child: PageView( - physics: NeverScrollableScrollPhysics(), - controller: _controller, - onPageChanged: (index) { - setState(() { - _currentIndex = index; - }); - }, - scrollDirection: Axis.horizontal, - children: [ - widget.model.pendingOrder != null - ? ListView(padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), children: [ - (Container( - decoration: BoxDecoration( - color: Color(0xffCC9B14), - borderRadius: BorderRadius.all( - Radius.circular(10.0), + return PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + widget.model.pendingOrder != null + ? ListView(padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), children: [ + (Container( + decoration: BoxDecoration( + color: Color(0xffCC9B14), + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + ), + child: Container( + // decoration: containerColorRadiusLeft(Colors.white, 12), + margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), + padding: EdgeInsets.symmetric(vertical: 14, horizontal: 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.only( + bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + ), + ), + // clipBehavior: Clip.antiAlias, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + (projectViewModel.isArabic ? widget.model.pendingOrder.descriptionN : widget.model.pendingOrder.description), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffCC9B14), letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${widget.model.pendingOrder.iD.toString()}', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).serviceName + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), ), - boxShadow: [ - BoxShadow( - color: Color(0xff000000).withOpacity(.05), - blurRadius: 27, - offset: Offset(0, -3), - ), - ], - ), + Column( + children: [ + ...List.generate( + widget.model.hhcAllOrderDetail.length, + (index) => Container( + child: Texts( + projectViewModel.isArabic ? widget.model.hhcAllOrderDetail[index].descriptionN : widget.model.hhcAllOrderDetail[index].description.capitalize(), + fontSize: 13, + bold: false, + ), + ), + ) + ], + ) + ], + ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.model.pendingOrder.createdOn)), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 12), + if (widget.model.pendingOrder.status == 1 || widget.model.pendingOrder.status == 2) + InkWell( + onTap: () { + showConfirmMessage(widget.model, widget.model.hhcAllOrderDetail[0]); + }, child: Container( - // decoration: containerColorRadiusLeft(Colors.white, 12), - margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), - padding: EdgeInsets.symmetric(vertical: 14, horizontal: 12), + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), decoration: BoxDecoration( - color: Colors.white, + color: Color(0xffD02127), border: Border.all(color: Colors.white, width: 1), - borderRadius: BorderRadius.only( - bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), - topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), - bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), - topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), - ), + borderRadius: BorderRadius.circular(10), ), - // clipBehavior: Clip.antiAlias, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - (projectViewModel.isArabic ? widget.model.pendingOrder.descriptionN : widget.model.pendingOrder.description), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffCC9B14), letterSpacing: -0.4, height: 16 / 10), - ), - SizedBox(height: 6), - Text( - '${TranslationBase.of(context).requestID}: ${widget.model.pendingOrder.iD.toString()}', - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).serviceName + ": ", - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), - ), - Column( - children: [ - ...List.generate( - widget.model.hhcAllOrderDetail.length, - (index) => Container( - child: Texts( - projectViewModel.isArabic - ? widget.model.hhcAllOrderDetail[index].descriptionN - : widget.model.hhcAllOrderDetail[index].description.capitalize(), - fontSize: 13, - bold: false, - ), - ), - ) - ], - ) - ], - ) - ], - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.model.pendingOrder.createdOn)), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), - ), - SizedBox(height: 12), - if (widget.model.pendingOrder.status == 1 || widget.model.pendingOrder.status == 2) - InkWell( - onTap: () { - showConfirmMessage(widget.model, widget.model.hhcAllOrderDetail[0]); - }, - child: Container( - padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), - decoration: BoxDecoration( - color: Color(0xffD02127), - border: Border.all(color: Colors.white, width: 1), - borderRadius: BorderRadius.circular(10), - ), - child: Text( - TranslationBase.of(context).cancel_nocaps, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), - ), - ), - ), - ], - ), - ], + child: Text( + TranslationBase.of(context).cancel_nocaps, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), ), ), - )) - ]) - - // FractionallySizedBox( - // widthFactor: 0.9, - // child: SingleChildScrollView( - // child: Container( - // // margin: EdgeInsets.all(10), - // child: Container( - // width: double.infinity, - // padding: EdgeInsets.only(left: 12, right: 12, top: 12), - // child: Card( - // shape: cardRadius(12), - // elevation: 2, - // margin: EdgeInsets.zero, - // color: Color(0xffcd9e1b), - // clipBehavior: Clip.antiAlias, - // child: Container( - // // decoration: containerColorRadiusLeft(Colors.white, 12), - // margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 8, right: projectViewModel.isArabic ? 8 : 0), - // padding: EdgeInsets.all(12), - // // color: Colors.white, - // decoration: BoxDecoration( - // shape: BoxShape.rectangle, - // color: Colors.white, - // borderRadius: BorderRadius.only( - // topLeft: projectViewModel.isArabic ? Radius.zero : Radius.circular(12.0), - // topRight: projectViewModel.isArabic ? Radius.circular(12.0) : Radius.zero, - // bottomLeft: projectViewModel.isArabic ? Radius.zero : Radius.circular(12.0), - // bottomRight: projectViewModel.isArabic ? Radius.circular(12.0) : Radius.zero, - // ), - // ), - // // clipBehavior: Clip.antiAlias, - // child: Row( - // children: [ - // Expanded( - // child: Column( - // mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Texts( - // TranslationBase.of(context).OrderStatus + - // ' ' + - // (projectViewModel.isArabic ? widget.model.pendingOrder.descriptionN : widget.model.pendingOrder.description), - // bold: false, - // fontSize: 12, - // color: Color(0xffcd9e1b), - // fontWeight: FontWeight.bold, - // ), - // Texts( - // TranslationBase.of(context).requestID + ' ' + widget.model.pendingOrder.iD.toString(), - // fontWeight: FontWeight.w600, - // fontSize: 18, - // ), - // Texts( - // TranslationBase.of(context).serviceName, - // fontSize: 12, - // fontWeight: FontWeight.w600, - // ), - // ...List.generate( - // widget.model.hhcAllOrderDetail.length, - // (index) => Container( - // child: Texts( - // projectViewModel.isArabic ? widget.model.hhcAllOrderDetail[index].descriptionN : widget.model.hhcAllOrderDetail[index].description.capitalize(), - // fontSize: 13, - // bold: false, - // ), - // ), - // ), - // ], - // )), - // Column( - // children: [ - // Texts( - // DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.model.pendingOrder.createdOn)), - // fontSize: 14, - // ), - // mHeight(8), - // // SecondaryButton( - // // onTap: () { - // // showConfirmMessage(widget.model, widget.model.hhcAllOrderDetail[0]); - // // }, - // // label: TranslationBase.of(context).cancel, - // // color: Colors.red[900], - // // small: true, - // // ) - // ], - // ), - // ], - // ))), - // )))) - : NewHomeHealthCareStepOnePage( - changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: patientERInsertPresOrderRequestModel, - model: widget.model, - ), - ], + ), + ], + ), + ], + ), ), - ), - ], - ), - ), - ), - ), + )) + ]) + + // FractionallySizedBox( + // widthFactor: 0.9, + // child: SingleChildScrollView( + // child: Container( + // // margin: EdgeInsets.all(10), + // child: Container( + // width: double.infinity, + // padding: EdgeInsets.only(left: 12, right: 12, top: 12), + // child: Card( + // shape: cardRadius(12), + // elevation: 2, + // margin: EdgeInsets.zero, + // color: Color(0xffcd9e1b), + // clipBehavior: Clip.antiAlias, + // child: Container( + // // decoration: containerColorRadiusLeft(Colors.white, 12), + // margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 8, right: projectViewModel.isArabic ? 8 : 0), + // padding: EdgeInsets.all(12), + // // color: Colors.white, + // decoration: BoxDecoration( + // shape: BoxShape.rectangle, + // color: Colors.white, + // borderRadius: BorderRadius.only( + // topLeft: projectViewModel.isArabic ? Radius.zero : Radius.circular(12.0), + // topRight: projectViewModel.isArabic ? Radius.circular(12.0) : Radius.zero, + // bottomLeft: projectViewModel.isArabic ? Radius.zero : Radius.circular(12.0), + // bottomRight: projectViewModel.isArabic ? Radius.circular(12.0) : Radius.zero, + // ), + // ), + // // clipBehavior: Clip.antiAlias, + // child: Row( + // children: [ + // Expanded( + // child: Column( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Texts( + // TranslationBase.of(context).OrderStatus + + // ' ' + + // (projectViewModel.isArabic ? widget.model.pendingOrder.descriptionN : widget.model.pendingOrder.description), + // bold: false, + // fontSize: 12, + // color: Color(0xffcd9e1b), + // fontWeight: FontWeight.bold, + // ), + // Texts( + // TranslationBase.of(context).requestID + ' ' + widget.model.pendingOrder.iD.toString(), + // fontWeight: FontWeight.w600, + // fontSize: 18, + // ), + // Texts( + // TranslationBase.of(context).serviceName, + // fontSize: 12, + // fontWeight: FontWeight.w600, + // ), + // ...List.generate( + // widget.model.hhcAllOrderDetail.length, + // (index) => Container( + // child: Texts( + // projectViewModel.isArabic ? widget.model.hhcAllOrderDetail[index].descriptionN : widget.model.hhcAllOrderDetail[index].description.capitalize(), + // fontSize: 13, + // bold: false, + // ), + // ), + // ), + // ], + // )), + // Column( + // children: [ + // Texts( + // DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.model.pendingOrder.createdOn)), + // fontSize: 14, + // ), + // mHeight(8), + // // SecondaryButton( + // // onTap: () { + // // showConfirmMessage(widget.model, widget.model.hhcAllOrderDetail[0]); + // // }, + // // label: TranslationBase.of(context).cancel, + // // color: Colors.red[900], + // // small: true, + // // ) + // ], + // ), + // ], + // ))), + // )))) + : NewHomeHealthCareStepOnePage( + changePageViewIndex: _changeCurrentTab, + patientERInsertPresOrderRequestModel: patientERInsertPresOrderRequestModel, + model: widget.model, + ), + ], ); } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart index 948ee8d6..a8deecf6 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart @@ -44,27 +44,6 @@ class OrdersLogDetailsPage extends StatelessWidget { ), ); return; - - // todo 'sikander' remove useless code - - showDialog( - context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3); - model.setState(ViewState.Busy); - await model.updateHHCPresOrder(updatePresOrderRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); - await model.getHHCAllPresOrders(); - // await model.getHHCAllServices(); - } - }, - ), - ); } return AppScaffold( diff --git a/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart deleted file mode 100644 index 0197873b..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -// todo 'sikander' remove useless code -// ignore: must_be_immutable -// class ConfirmAddAmountDialog extends StatefulWidget { -// final int amount; -// final String unit; -// final H2OViewModel model; -// -// ConfirmAddAmountDialog({Key key, this.model, this.amount, this.unit = "ml"}); -// -// @override -// _ConfirmAddAmountDialogState createState() => _ConfirmAddAmountDialogState(); -// } -// -// class _ConfirmAddAmountDialogState extends State { -// @override -// void initState() { -// super.initState(); -// } -// -// @override -// Widget build(BuildContext context) { -// return SimpleDialog( -// contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 24.0, 8.0), -// titlePadding: EdgeInsets.fromLTRB(24.0, 16.0, 24.0, 8.0), -// title: Center( -// child: Texts( -// TranslationBase.of(context).confirm, -// textAlign: TextAlign.center, -// color: Colors.black, -// ), -// ), -// children: [ -// Column( -// children: [ -// Divider(), -// Center( -// child: Texts( -// "${TranslationBase.of(context).areyousure} ${widget.amount} ${widget.unit} ?", -// textAlign: TextAlign.center, -// color: Colors.grey, -// ), -// ), -// SizedBox( -// height: 16.0, -// ), -// Row( -// // mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// Navigator.pop(context); -// }, -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Container( -// child: Center( -// child: Texts( -// TranslationBase.of(context).cancel.toUpperCase(), -// color: Colors.red, -// ), -// ), -// ), -// ), -// ), -// ), -// Container( -// width: 1, -// height: 30, -// color: Colors.grey[500], -// ), -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () async { -// InsertUserActivityRequestModel insertUserActivityRequestModel = InsertUserActivityRequestModel(quantityIntake: widget.amount); -// await widget.model.insertUserActivity(insertUserActivityRequestModel); -// Navigator.pop(context); -// }, -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Center( -// child: Texts( -// TranslationBase.of(context).ok.toUpperCase(), -// fontWeight: FontWeight.w400, -// )), -// ), -// ), -// ), -// ], -// ), -// ], -// ) -// ], -// ); -// } -// } diff --git a/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart deleted file mode 100644 index 4d02c27b..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -// todo 'sikander' remove useless code -// ignore: must_be_immutable -// class SelectAmountDialog extends StatefulWidget { -// final Function(AmountModel) onValueSelected; -// AmountModel selectedAmount; -// -// SelectAmountDialog({Key key, this.onValueSelected, this.selectedAmount}); -// -// @override -// _SelectAmountDialogState createState() => _SelectAmountDialogState(); -// } -// -// class _SelectAmountDialogState extends State { -// List searchAmount = [ -// AmountModel(name: "l", nameAr: "لتر", value: 1), -// AmountModel(name: "ml", nameAr: "مم لتر", value: 2), -// ]; -// @override -// void initState() { -// super.initState(); -// widget.selectedAmount = widget.selectedAmount ?? searchAmount[0]; -// getLanguage(); -// } -// -// String languageID = "en"; -// -// void getLanguage() async { -// languageID = await sharedPref.getString(APP_LANGUAGE); -// setState(() {}); -// } -// -// @override -// Widget build(BuildContext context) { -// return SimpleDialog( -// children: [ -// Column( -// children: [ -// Texts( -// TranslationBase.of(context).preferredunit, -// fontSize: 20, -// ), -// Divider(), -// ...List.generate( -// searchAmount.length, -// (index) => Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// SizedBox( -// height: 2, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// setState(() { -// widget.selectedAmount = searchAmount[index]; -// }); -// }, -// child: ListTile( -// title: Text(languageID == "ar" ? searchAmount[index].nameAr : searchAmount[index].name), -// leading: Radio( -// value: searchAmount[index], -// groupValue: widget.selectedAmount, -// activeColor: Colors.red[800], -// onChanged: (value) { -// setState(() { -// widget.selectedAmount = value; -// }); -// }, -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// ], -// ), -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// // mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// Navigator.pop(context); -// }, -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Container( -// child: Center( -// child: Texts( -// TranslationBase.of(context).cancel.toUpperCase(), -// color: Colors.red, -// ), -// ), -// ), -// ), -// ), -// ), -// Container( -// width: 1, -// height: 30, -// color: Colors.grey[500], -// ), -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// widget.onValueSelected(widget.selectedAmount); -// Navigator.pop(context); -// }, -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Center( -// child: Texts( -// TranslationBase.of(context).ok, -// fontWeight: FontWeight.w400, -// )), -// ), -// ), -// ), -// ], -// ) -// ], -// ) -// ], -// ); -// } -// } -// -// class AmountModel { -// String name; -// String nameAr; -// int value; -// -// AmountModel({this.name, this.nameAr, this.value}); -// -// AmountModel.fromJson(Map json) { -// name = json['name']; -// nameAr = json['nameAr']; -// value = json['value']; -// } -// -// Map toJson() { -// final Map data = new Map(); -// data['name'] = this.name; -// data['nameAr'] = this.nameAr; -// data['value'] = this.value; -// return data; -// } -// } diff --git a/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart b/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart deleted file mode 100644 index 641f6df7..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart'; -import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'Dialog/select_amount_dialog.dart'; - -// todo 'sikander' remove useless code -// class AddCustomAmount extends StatefulWidget { -// final H2OViewModel model; -// final Function changePageViewIndex; -// -// const AddCustomAmount({Key key, this.model, this.changePageViewIndex}) -// : super(key: key); -// -// @override -// _AddCustomAmountState createState() => _AddCustomAmountState(); -// } -// -// class _AddCustomAmountState extends State { -// TextEditingController _nameTextController = TextEditingController(); -// AmountModel selectedAmount; -// -// @override -// void initState() { -// setState(() { -// _nameTextController.text = "0"; -// }); -// super.initState(); -// } -// -// @override -// Widget build(BuildContext context) { -// return AppScaffold( -// isShowAppBar: true, -// appBarTitle:TranslationBase.of(context).customLabel, -// body: SingleChildScrollView( -// physics: ScrollPhysics(), -// child: Container( -// margin: EdgeInsets.all(12), -// child: Center( -// child: FractionallySizedBox( -// widthFactor: 0.94, -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).h2oAmountOfWater, -// // type: "Number", -// controller: _nameTextController, -// ), -// SizedBox( -// height: 12, -// ), -// InkWell( -// onTap: () => confirmAmountTypeDialog(), -// child: Container( -// padding: EdgeInsets.all(12), -// width: double.infinity, -// height: 65, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(12), -// color: Colors.white), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts(getAmountName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// SecondaryButton( -// textColor: Colors.white, -// label: TranslationBase.of(context).ok, -// onTap: () async { -// Navigator.of(context).pop(); -// showConfirmMessage (int.parse(_nameTextController.text), widget.model); -// }, -// // loading: model.state == ViewState.BusyLocal, -// disabled: _nameTextController.text.isEmpty || selectedAmount == null), -// SizedBox( -// height: 12, -// ), -// ], -// ), -// ), -// ), -// ), -// ), -// ); -// } -// -// -// void confirmAmountTypeDialog() { -// showDialog( -// context: context, -// child: SelectAmountDialog( -// selectedAmount: selectedAmount, -// onValueSelected: (value) { -// setState(() { -// selectedAmount = value; -// }); -// }, -// ), -// ); -// } -// -// -// String getAmountName() { -// if (selectedAmount != null) -// return selectedAmount.name; -// else -// return TranslationBase.of(context).selectUnit; -// } -// -// -// -// void showConfirmMessage(int amount, H2OViewModel model) { -// showDialog(context: context, child: ConfirmAddAmountDialog(model: model,amount:amount,)); -// } -// } diff --git a/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart b/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart index 904f4183..edc82034 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart @@ -126,7 +126,7 @@ class _H2oSettingState extends State { ), ), SizedBox(height: 12), - _containerWidget(inputWidget(TranslationBase.of(context).enterNameHere, TranslationBase.of(context).name, _nameController)), + inputWidget(TranslationBase.of(context).enterNameHere, TranslationBase.of(context).name, _nameController).withBorderedContainer, SizedBox(height: 16), Text( TranslationBase.of(context).preferredunit, @@ -210,80 +210,77 @@ class _H2oSettingState extends State { }, _weightPopupList), SizedBox(height: 12), - _containerWidget( - _commonDropDownView(TranslationBase.of(context).dateOfBirth, DateUtil.getFormattedDate(_dobDate, "dd MMMM, yyyy"), () { - showModalBottomSheet( - context: context, - builder: (context) { - return Container( - height: 250, - padding: EdgeInsets.all(8), - child: Column(children: [ - Container( - height: 40, - alignment: Alignment.centerRight, - child: Row(mainAxisSize: MainAxisSize.min, children: [ - InkWell( - onTap: () => Navigator.pop(context), - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.fromLTRB(8, 4, 8, 4), - child: Text(TranslationBase.of(context).cancel), - ), + CommonDropDownView(TranslationBase.of(context).dateOfBirth, DateUtil.getFormattedDate(_dobDate, "dd MMMM, yyyy"), () { + showModalBottomSheet( + context: context, + builder: (context) { + return Container( + height: 250, + padding: EdgeInsets.all(8), + child: Column(children: [ + Container( + height: 40, + alignment: Alignment.centerRight, + child: Row(mainAxisSize: MainAxisSize.min, children: [ + InkWell( + onTap: () => Navigator.pop(context), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.fromLTRB(8, 4, 8, 4), + child: Text(TranslationBase.of(context).cancel), ), - SizedBox(width: 8), - InkWell( - onTap: () { - Navigator.pop(context); - setState(() { - _dobDate = _tempDate; - }); - }, - child: Container( - alignment: Alignment.center, - padding: EdgeInsets.fromLTRB(8, 4, 8, 4), - child: Text(TranslationBase.of(context).ok), - ), - ) - ]), - ), - Expanded( - child: Container( - width: MediaQuery.of(context).size.width, - child: CupertinoDatePicker( - initialDateTime: _dobDate, - mode: CupertinoDatePickerMode.date, - onDateTimeChanged: (_date) { - _tempDate = _date; - }, + ), + SizedBox(width: 8), + InkWell( + onTap: () { + Navigator.pop(context); + setState(() { + _dobDate = _tempDate; + }); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.fromLTRB(8, 4, 8, 4), + child: Text(TranslationBase.of(context).ok), ), + ) + ]), + ), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + child: CupertinoDatePicker( + initialDateTime: _dobDate, + mode: CupertinoDatePickerMode.date, + onDateTimeChanged: (_date) { + _tempDate = _date; + }, ), - ) - ]), - ); - }); - }, iconData: Icons.calendar_today), - ), + ), + ) + ]), + ); + }); + }, iconData: Icons.calendar_today) + .withBorderedContainer, SizedBox(height: 12), - _containerWidget( - _commonDropDownView(TranslationBase.of(context).activityLevel, _activityLevelListEng[_selectedActiveLevel - 1], () { - List list = [ - for (int i = 0; i < _activityLevelListEng.length; i++) RadioSelectionDialogModel(_activityLevelListEng[i], i + 1), - ]; + CommonDropDownView(TranslationBase.of(context).activityLevel, _activityLevelListEng[_selectedActiveLevel - 1], () { + List list = [ + for (int i = 0; i < _activityLevelListEng.length; i++) RadioSelectionDialogModel(_activityLevelListEng[i], i + 1), + ]; - showDialog( - context: context, - child: RadioSelectionDialog( - listData: list, - selectedIndex: _selectedActiveLevel, - onValueSelected: (index) { - _selectedActiveLevel = index; - setState(() {}); - }, - ), - ); - }), - ), + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedActiveLevel, + onValueSelected: (index) { + _selectedActiveLevel = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, SizedBox(height: 18), Text( TranslationBase.of(context).reminderLabel, @@ -296,25 +293,23 @@ class _H2oSettingState extends State { ), ), SizedBox(height: 12), - _containerWidget( - _commonDropDownView(TranslationBase.of(context).reminderTimesLabel, _remindedTimeListEng[_selectedRemindedTime], () { - List list = [ - for (int i = 0; i < _remindedTimeListEng.length; i++) RadioSelectionDialogModel(_remindedTimeListEng[i], i), - ]; + CommonDropDownView(TranslationBase.of(context).reminderTimesLabel, _remindedTimeListEng[_selectedRemindedTime], () { + List list = [ + for (int i = 0; i < _remindedTimeListEng.length; i++) RadioSelectionDialogModel(_remindedTimeListEng[i], i), + ]; - showDialog( - context: context, - child: RadioSelectionDialog( - listData: list, - selectedIndex: _selectedRemindedTime, - onValueSelected: (index) { - _selectedRemindedTime = index; - setState(() {}); - }, - ), - ); - }), - ), + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedRemindedTime, + onValueSelected: (index) { + _selectedRemindedTime = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, ], ), ), @@ -333,58 +328,6 @@ class _H2oSettingState extends State { ); } - Widget _containerWidget(Widget child) { - return Container( - padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Colors.white, - border: Border.all( - color: Color(0xffefefef), - width: 1, - ), - ), - child: child, - ); - } - - Widget _commonDropDownView(String title, String value, VoidCallback callback, {IconData iconData}) { - return InkWell( - onTap: callback, - child: Row( - children: [ - Expanded( - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - title, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2E303A), - letterSpacing: -0.44, - ), - ), - Text( - value, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w400, - color: Color(0xff575757), - letterSpacing: -0.56, - ), - ), - ]), - ), - Icon( - iconData ?? Icons.keyboard_arrow_down_sharp, - color: Color(0xff2E303A), - ) - ], - ), - ); - } - Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { return InkWell( onTap: hasSelection ? () {} : null, @@ -501,81 +444,79 @@ class _H2oSettingState extends State { Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, Function(bool) onUnitTap, _list) { - return _containerWidget( - Row( - children: [ - Expanded( - flex: 3, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _title, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2E303A), - letterSpacing: -0.44, - ), + return Row( + children: [ + Expanded( + flex: 3, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.44, ), - TextField( - controller: _controller, - keyboardType: TextInputType.number, - onChanged: (value) { - double _value = double.parse(value); - if (_value > _maxValue) { - onTextValueChange(_maxValue.toStringAsFixed(0)); - onValueChange(_maxValue); - return; - } else if (_value < _minValue) { - onTextValueChange(_minValue.toStringAsFixed(0)); - onValueChange(_minValue); - return; - } else if (_value >= _minValue && _value <= _maxValue) { - onValueChange(_value); - return; - } - }, - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), - ], - style: TextStyle( + ), + TextField( + controller: _controller, + keyboardType: TextInputType.number, + onChanged: (value) { + double _value = double.parse(value); + if (_value > _maxValue) { + onTextValueChange(_maxValue.toStringAsFixed(0)); + onValueChange(_maxValue); + return; + } else if (_value < _minValue) { + onTextValueChange(_minValue.toStringAsFixed(0)); + onValueChange(_minValue); + return; + } else if (_value >= _minValue && _value <= _maxValue) { + onValueChange(_value); + return; + } + }, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + ], + style: TextStyle( + color: Color(0xff575757), + letterSpacing: -0.56, + ), + decoration: InputDecoration( + isDense: true, + hintText: "0", + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, color: Color(0xff575757), letterSpacing: -0.56, ), - decoration: InputDecoration( - isDense: true, - hintText: "0", - hintStyle: TextStyle( - fontSize: 14, - height: 21 / 14, - fontWeight: FontWeight.w400, - color: Color(0xff575757), - letterSpacing: -0.56, - ), - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), - ], - ), + ), + ], ), - Container(height: 34, width: 1, color: Color(0xffE0E0E0), margin: EdgeInsets.only(left: 12, right: 12)), - Expanded( - flex: 1, - child: PopupMenuButton( - child: _commonDropDownView(TranslationBase.of(context).unit, unitTitle, null), - onSelected: (value) { - onUnitTap(value); - }, - itemBuilder: (context) => _list), - ) - ], - ), - ); + ), + Container(height: 34, width: 1, color: Color(0xffE0E0E0), margin: EdgeInsets.only(left: 12, right: 12)), + Expanded( + flex: 1, + child: PopupMenuButton( + child: CommonDropDownView(TranslationBase.of(context).unit, unitTitle, null), + onSelected: (value) { + onUnitTap(value); + }, + itemBuilder: (context) => _list), + ) + ], + ).withBorderedContainer; } void _updateUserDetails() async { @@ -627,3 +568,65 @@ class _H2oSettingState extends State { }); } } + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatelessWidget { + final String title; + final String value; + final VoidCallback callback; + final IconData iconData; + CommonDropDownView(this.title, this.value, this.callback, {Key key, this.iconData}) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: callback, + child: Row( + children: [ + Expanded( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.44, + ), + ), + Text( + value, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ]), + ), + Icon( + iconData ?? Icons.keyboard_arrow_down_sharp, + color: Color(0xff2E303A), + ) + ], + ), + ); + } +} + +extension BorderedContainer on Widget { + Widget get withBorderedContainer => Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: this, + ); +} diff --git a/lib/pages/AlHabibMedicalService/h2o/today_page.dart b/lib/pages/AlHabibMedicalService/h2o/today_page.dart index 583dabbf..97717c64 100644 --- a/lib/pages/AlHabibMedicalService/h2o/today_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/today_page.dart @@ -1,7 +1,6 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -18,9 +17,6 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:wave/config.dart'; import 'package:wave/wave.dart'; -import 'Dialog/confirm_add_amount_dialog.dart'; -import 'add_custom_amount.dart'; - class TodayPage extends StatefulWidget { TodayPage({Key key}) : super(key: key); diff --git a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart b/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart deleted file mode 100644 index 9b876cc1..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart +++ /dev/null @@ -1,201 +0,0 @@ -import 'dart:math' as math; - -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; - -import '../add_custom_amount.dart'; - - -// todo 'sikander' remove useless code - - -// class H20FloatingActionButton extends StatefulWidget { -// const H20FloatingActionButton({Key key, @required AnimationController controller, @required this.model}) : super(key: key); -// -// final H2OViewModel model; -// -// @override -// _H20FloatingActionButtonState createState() => _H20FloatingActionButtonState(); -// } -// -// class _H20FloatingActionButtonState extends State with TickerProviderStateMixin { -// AnimationController _controller; -// @override -// void initState() { -// _controller = new AnimationController( -// vsync: this, -// duration: const Duration(milliseconds: 500), -// ); -// super.initState(); -// } -// -// void showConfirmMessage(int amount, H2OViewModel model) { -// showDialog( -// context: context, -// child: ConfirmAddAmountDialog( -// model: model, -// amount: amount, -// ), -// ); -// } -// -// @override -// Widget build(BuildContext context) { -// return Container( -// margin: EdgeInsets.only(left: 20, right: 20), -// child: new Column(mainAxisSize: MainAxisSize.min, children: [ -// Row( -// mainAxisAlignment: MainAxisAlignment.start, -// children: [ -// Column( -// crossAxisAlignment: CrossAxisAlignment.end, -// children: [ -// ActionButton( -// controller: _controller, -// text: "600${TranslationBase.of(context).ml}", -// onTap: () { -// showConfirmMessage(600, widget.model); -// }, -// ), -// ActionButton( -// controller: _controller, -// text: "330${TranslationBase.of(context).ml}", -// onTap: () { -// showConfirmMessage(330, widget.model); -// }, -// ), -// ActionButton( -// controller: _controller, -// text: "200${TranslationBase.of(context).ml}", -// onTap: () { -// showConfirmMessage(200, widget.model); -// }, -// ), -// ], -// ), -// ], -// ), -// Row( -// mainAxisAlignment: MainAxisAlignment.start, -// children: [ -// FloatingActionButton( -// heroTag: null, -// child: new AnimatedBuilder( -// animation: _controller, -// builder: (BuildContext context, Widget child) { -// return new Transform( -// transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi), -// alignment: FractionalOffset.center, -// child: new Icon(_controller.isDismissed ? Icons.add : Icons.close), -// ); -// }, -// ), -// onPressed: () { -// if (_controller.isDismissed) { -// _controller.forward(); -// } else { -// _controller.reverse(); -// } -// }, -// ), -// new Container( -// margin: EdgeInsets.only(left: 8, bottom: 4), -// alignment: FractionalOffset.topCenter, -// child: new ScaleTransition( -// scale: new CurvedAnimation( -// parent: _controller, -// curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), -// ), -// child: new FloatingActionButton( -// backgroundColor: Colors.white, -// heroTag: null, -// // mini: true, -// child: Text( -// TranslationBase.of(context).custom, -// textAlign: TextAlign.center, -// style: TextStyle(fontSize: 12, color: Colors.grey), -// ), -// onPressed: () { -// Navigator.push( -// context, -// FadePage( -// page: AddCustomAmount( -// model: widget.model, -// ), -// ), -// ); -// }, -// ), -// ), -// ), -// new Container( -// margin: EdgeInsets.only(left: 8, bottom: 4), -// alignment: FractionalOffset.topCenter, -// child: new ScaleTransition( -// scale: new CurvedAnimation( -// parent: _controller, -// curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), -// ), -// child: new FloatingActionButton( -// backgroundColor: Colors.white, -// heroTag: null, -// //mini: true, -// child: Text( -// TranslationBase.of(context).undo, -// textAlign: TextAlign.center, -// style: TextStyle(fontSize: 12.0, color: Colors.grey), -// ), -// onPressed: undoVolume, -// ), -// ), -// ), -// ], -// ), -// ]), -// ); -// } -// -// void undoVolume() async { -// GifLoaderDialogUtils.showMyDialog(context); -// await widget.model.undoUserActivity(); -// GifLoaderDialogUtils.hideDialog(context); -// } -// } -// -// class ActionButton extends StatelessWidget { -// const ActionButton({Key key, @required AnimationController controller, @required this.text, this.onTap}) -// : _controller = controller, -// super(key: key); -// -// final AnimationController _controller; -// final String text; -// final Function onTap; -// -// @override -// Widget build(BuildContext context) { -// return Container( -// margin: EdgeInsets.only(left: 4, bottom: 8), -// alignment: FractionalOffset.topCenter, -// child: new ScaleTransition( -// scale: new CurvedAnimation( -// parent: _controller, -// curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), -// ), -// child: new FloatingActionButton( -// heroTag: null, -// backgroundColor: Colors.white, -// //mini: true, -// child: Text( -// text, -// textAlign: TextAlign.center, -// style: TextStyle(fontSize: 12.0, color: Colors.grey), -// ), -// onPressed: onTap), -// ), -// ); -// } -// } diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index e3888240..ffb7e1ee 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; + //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; @@ -10,14 +11,14 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_mod import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectCiteisDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -26,8 +27,6 @@ import 'package:giffy_dialog/giffy_dialog.dart'; import 'package:provider/provider.dart'; import 'dialogs/SelectBeneficiaryDialog.dart'; -import 'dialogs/SelectBloodDialog.dart'; -import 'dialogs/SelectGenderDialog.dart'; import 'dialogs/SelectPatientFamilyDialog.dart'; import 'dialogs/SelectPatientInfoDialog.dart'; @@ -44,11 +43,16 @@ class _BloodDonationPageState extends State { TextEditingController _fileTextController = TextEditingController(); TextEditingController _notesTextController = TextEditingController(); BeneficiaryType beneficiaryType = BeneficiaryType.NON; - Gender gender = Gender.Male; //Gender.NON; - Blood blood = Blood.Aminus; //Blood.NON; + + // Gender gender = Gender.Male; //Gender.NON; + // Blood blood = Blood.Aminus; //Blood.NON; //HospitalsModel _selectedHospital; CitiesModel _selectedHospital; + int _selectedHospitalIndex = 0; + int _selectedGenderIndex = 1; + int _selectedBloodTypeIndex = 0; + String amount = ""; String email; PatientInfo _selectedPatientInfo; @@ -81,182 +85,193 @@ class _BloodDonationPageState extends State { return BaseView( onModelReady: (model) => model.getCities(), //model.getHospitals(), builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - showNewAppBar: true, - showNewAppBarTitle: true, - baseViewModel: model, - imagesInfo: imagesInfo, - description: TranslationBase.of(context).bloodDonationInfo, - appBarTitle: TranslationBase.of(context).bloodD, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).bloodDEnterDesc - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectHospitalDialog(model.CitiesModelList), - //model.hospitals - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts(getHospitalName(projectProvider, context), color: Colors.black), Icon(Icons.arrow_drop_down)], - ), - ), - ), - SizedBox( - height: 12, - ), - InkWell( - //======Gender======== - onTap: () => confirmSelectGenderDialog(), - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getGender(context), color: Colors.black), - Icon(Icons.arrow_drop_down) - ], - ), + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF7F7F7), + showNewAppBarTitle: true, + baseViewModel: model, + imagesInfo: imagesInfo, + description: TranslationBase.of(context).bloodDonationInfo, + appBarTitle: TranslationBase.of(context).bloodD, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).bloodDEnterDesc, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), ), - ), - SizedBox( - height: 12, - ), - InkWell( - //======Gender======== - onTap: () => confirmSelectBloodDialog(), - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts(getBlood(), color: Colors.black), Icon(Icons.arrow_drop_down)], - ), - ), - ), - SizedBox( - height: 12, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - child: Text( + SizedBox(height: 12), + CommonDropDownView( + TranslationBase.of(context).city, + model.CitiesModelList.isNotEmpty + ? projectProvider.isArabic + ? model.CitiesModelList[_selectedHospitalIndex].descriptionN + : model.CitiesModelList[_selectedHospitalIndex].description + : "", () { + List list = [ + for (int i = 0; i < model.CitiesModelList.length; i++) + RadioSelectionDialogModel(projectProvider.isArabic ? model.CitiesModelList[i].descriptionN : model.CitiesModelList[i].description, i), + ]; + + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = model.CitiesModelList[index]; + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + CommonDropDownView(TranslationBase.of(context).gender, _selectedGenderIndex == 1 ? TranslationBase.of(context).male : TranslationBase.of(context).female, () { + List list = [ + RadioSelectionDialogModel(TranslationBase.of(context).male, 1), + RadioSelectionDialogModel(TranslationBase.of(context).female, 2), + ]; + + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedGenderIndex, + onValueSelected: (index) { + _selectedGenderIndex = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + CommonDropDownView(TranslationBase.of(context).bloodType, getBlood(_selectedBloodTypeIndex), () { + List list = [ + RadioSelectionDialogModel("O+", 0), + RadioSelectionDialogModel("O-", 1), + RadioSelectionDialogModel("AB+", 2), + RadioSelectionDialogModel("AB-", 3), + RadioSelectionDialogModel("A+", 4), + RadioSelectionDialogModel("A-", 5), + RadioSelectionDialogModel("B+", 6), + RadioSelectionDialogModel("B-", 7), + ]; + + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedBloodTypeIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedBloodTypeIndex = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( TranslationBase.of(context).viewTermsConditions + ":", - style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xff2E303A), fontSize: 14, letterSpacing: -0.56), ), - ), - InkWell( - onTap: () { - Navigator.of(context).push(FadePage(page: UserAgreementPage())); - }, - child: Container( - child: Texts( + InkWell( + onTap: () { + Navigator.of(context).push(FadePage(page: UserAgreementPage())); + }, + child: Text( TranslationBase.of(context).clickHere, - color: Colors.blue, - fontSize: 14.0, + style: TextStyle(fontWeight: FontWeight.w600, color: Colors.blue, fontSize: 14, letterSpacing: -0.56), ), + ) + ], + ), + SizedBox(height: 12), + Row( + children: [ + Checkbox( + onChanged: (bool value) { + setState(() { + checkedValue = value; + }); + }, + value: checkedValue, + activeColor: Color(0xFFc5272d), + ), + Text( + TranslationBase.of(context).iAgreeToTheTermsAndConditions, + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold), ), - ) - ], - ), - SizedBox( - height: 12, - ), - Row( - children: [ - Checkbox( - onChanged: (bool value) { - setState(() { - checkedValue = value; - }); - }, - value: checkedValue, - activeColor: Color(0xFFc5272d), - ), - Text( - TranslationBase.of(context).iAgreeToTheTermsAndConditions, - style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold), - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Center( - child: Container( - color: Theme.of(context).primaryColor, - width: 350, - child: InkWell( - onTap: () { - showDialog( - context: context, - builder: (_) => AssetGiffyDialog( - title: Text( - "", - style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600), - ), - image: Image.asset('assets/images/BloodChrt_EN.png'), - buttonCancelText: Text(TranslationBase.of(context).cancel), - buttonCancelColor: Colors.grey, - onlyCancelButton: true, - )); - }, - child: Container(width: 250, height: 200, child: Image.asset('assets/images/BloodChrt_EN.png'), color: Colors.white), + ], + ), + SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center( + child: Container( + color: Theme.of(context).primaryColor, + width: 350, + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (_) => AssetGiffyDialog( + title: Text( + "", + style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600), + ), + image: Image.asset('assets/images/BloodChrt_EN.png'), + buttonCancelText: Text(TranslationBase.of(context).cancel), + buttonCancelColor: Colors.grey, + onlyCancelButton: true, + )); + }, + child: Container(width: 250, height: 200, child: Image.asset('assets/images/BloodChrt_EN.png'), color: Colors.white), + ), ), ), - ), - ], - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ) - ], + ], + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ) + ], + ), ), ), - ), - bottomSheet: Container( - width: double.infinity, - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(20), - child: DefaultButton(TranslationBase.of(context).save, () async { + DefaultButton(TranslationBase.of(context).save, () async { if (_selectedHospital == null) { AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); return; } bloodDetails.city = projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; bloodDetails.cityCode = _selectedHospital.iD.toString(); - bloodDetails.gender = gender == Gender.Male ? 1 : 2; + bloodDetails.gender = _selectedGenderIndex; + bloodDetails.bloodGroup = getBlood(_selectedBloodTypeIndex); await model.updateBloodGroup(bloodDetails); if (model.state == ViewState.Idle) { AppToast.showSuccessToast(message: model.updatedRegisterBloodMessage); } else { AppToast.showErrorToast(message: model.error); } - }), - )), + }).insideContainer + ], + ), + ), ); } @@ -280,106 +295,6 @@ class _BloodDonationPageState extends State { ); } - void confirmSelectBloodDialog() { - showDialog( - context: context, - child: SelectBloodDialog( - bloodType: blood, - onValueSelected: (value) { - setState(() { - if (value == Blood.Oplus) { - bloodDetails.bloodGroup = "O+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.Ominus) { - // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.bloodGroup = "O-"; - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.ABplus) { - bloodDetails.bloodGroup = "AB+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.ABminus) { - bloodDetails.bloodGroup = "AB-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.Aplus) { - bloodDetails.bloodGroup = "A+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.Aminus) { - bloodDetails.bloodGroup = "A-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.Bplus) { - bloodDetails.bloodGroup = "B+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else if (value == Blood.Bminus) { - bloodDetails.bloodGroup = "B-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else - _fileTextController.text = ""; - - // beneficiaryType = value; - blood = value; - }); - }, - ), - ); - } - - void confirmSelectGenderDialog() { - showDialog( - context: context, - child: SelectGenderDialog( - beneficiaryType: gender, - onValueSelected: (value) { - setState(() { - if (value == Gender.Male) { - // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.patientType = 1; - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else - // _fileTextController.text = ""; - { - bloodDetails.gender = 2; - } - - // beneficiaryType = value; - gender = value; - }); - }, - ), - ); - } - -//void confirmSelectHospitalDialog(List hospitals) { - void confirmSelectHospitalDialog(List hospitals) { - showDialog( - context: context, - child: SelectCiteisDialog( - hospitals: hospitals, - selectedHospital: _selectedHospital, - onValueSelected: (value) { - setState(() { - _selectedHospital = value; - }); - }, - ), - ); - } - void confirmSelectPatientDialog(List patientInfoList) { showDialog( context: context, @@ -429,54 +344,39 @@ class _BloodDonationPageState extends State { return TranslationBase.of(context).selectBeneficiary; } - String getGender(BuildContext context) { - switch (gender) { - case Gender.Male: - return TranslationBase.of(context).male; - case Gender.Female: - return TranslationBase.of(context).female; - break; - - case Gender.NON: - return TranslationBase.of(context).selectGender; - } - return TranslationBase.of(context).selectGender; - } - - String getBlood() { - switch (blood) { - case Blood.Oplus: + String getBlood(int index) { + switch (index) { + case 0: return "O+"; break; - case Blood.Ominus: + case 1: return "O-"; break; - case Blood.ABplus: + case 2: return "AB+"; break; - case Blood.ABminus: + case 3: return "AB-"; break; - case Blood.Aplus: + case 4: return "A+"; break; - case Blood.Aminus: + case 5: return "A-"; break; - case Blood.Bplus: + case 6: return "B-"; break; - case Blood.Bminus: + case 7: return "B-"; break; - case Blood.Bplus: + case 8: return "B+"; break; - case Blood.NON: - return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; + default: + return ""; } - return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; } String getHospitalName(ProjectViewModel projectProvider, BuildContext context) { diff --git a/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart b/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart deleted file mode 100644 index b31d4a38..00000000 --- a/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -// todo 'sikander' remove useless code -// class ConfirmExitPageDialog extends StatelessWidget { -// final GestureTapCallback onTapYes; -// final GestureTapCallback onTapNo; -// -// const ConfirmExitPageDialog({Key key, this.onTapYes, this.onTapNo}) -// : super(key: key); -// -// @override -// Widget build(BuildContext context) { -// return SimpleDialog( -// contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), -// title: Center( -// child: Texts( -// TranslationBase.of(context).confirm, -// color: Colors.black, -// ), -// ), -// children: [ -// Column( -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Texts( -// "Are you sure you want to exit this page ?", -// color: Colors.grey, -// ), -// SizedBox( -// height: 5, -// ), -// Divider(), -// SizedBox( -// height: 5.0, -// ), -// Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// InkWell( -// onTap: () { -// onTapNo(); -// }, -// child: Container( -// child: Center( -// child: Texts( -// TranslationBase.of(context).no, -// color: Colors.red, -// ), -// ), -// ), -// ), -// -// InkWell( -// onTap: () { -// Navigator.pop(context); -// onTapYes(); -// }, -// child: Container( -// child: Center( -// child: Texts(TranslationBase.of(context).yes), -// ), -// ), -// ), -// ], -// ), -// SizedBox( -// height: 20.0, -// ), -// ], -// ) -// ], -// ); -// } -// } diff --git a/lib/pages/ErService/EdOnline/DdServicesPage.dart b/lib/pages/ErService/EdOnline/DdServicesPage.dart index 457e199c..dc2e8d78 100644 --- a/lib/pages/ErService/EdOnline/DdServicesPage.dart +++ b/lib/pages/ErService/EdOnline/DdServicesPage.dart @@ -5,8 +5,6 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - -import 'ConfirmExitPageDialog.dart'; import 'EdOnlineAgreementPage.dart'; import 'EdOnlineNotesPage.dart'; import 'EdOnlineQuestionsPage.dart'; @@ -104,21 +102,4 @@ class _DdServicesPageState extends State { ), ); } - - // todo 'sikander' remove useless code - // void showConfirmMessage( - // BuildContext context, - // ) { - // showDialog( - // context: context, - // child: ConfirmExitPageDialog( - // onTapYes: () { - // Navigator.pop(context); - // }, - // onTapNo: () { - // Navigator.pop(context); - // }, - // ), - // ); - // } } diff --git a/lib/pages/feedback/send_feedback_page.dart b/lib/pages/feedback/send_feedback_page.dart index dc1b47f7..298e617e 100644 --- a/lib/pages/feedback/send_feedback_page.dart +++ b/lib/pages/feedback/send_feedback_page.dart @@ -498,42 +498,6 @@ class _SendFeedbackPageState extends State { ); return; - // todo 'sikander' remove useless code - // showDialog( - // context: context, - // child: FeedbackTypeDialog( - // messageTypeDialog: messageType, - // onValueSelected: (MessageType value) { - // if (value == MessageType.ComplaintOnAnAppointment) { - // appoList.clear(); - // GifLoaderDialogUtils.showMyDialog(context); - // service.getPatientAppointmentHistory(false, context, isForCOC: true).then((res) { - // GifLoaderDialogUtils.hideDialog(context); - // setState(() { - // if (res['MessageStatus'] == 1) { - // if (res['AppoimentAllHistoryResultList'].length != 0) { - // res['AppoimentAllHistoryResultList'].forEach((v) { - // appoList.add(new AppoitmentAllHistoryResultList.fromJson(v)); - // }); - // setState(() { - // appointHistory = null; - // isShowListAppointHistory = true; - // }); - // } else {} - // } else {} - // }); - // }).catchError((err) { - // GifLoaderDialogUtils.hideDialog(context); - // // print(err); - // // AppToast.showErrorToast(message: err); - // // Navigator.of(context).pop(); - // }); - // } else { - // isShowListAppointHistory = false; - // } - // setMessageType(value); - // }, - // )); } openSpeechReco() async { @@ -586,239 +550,4 @@ class _SendFeedbackPageState extends State { print(hasSpeech); if (!mounted) return; } -} -// todo 'sikander' remove useless code -// class FeedbackTypeDialog extends StatefulWidget { -// final Function(MessageType) onValueSelected; -// final MessageType messageTypeDialog; -// -// const FeedbackTypeDialog({Key key, this.onValueSelected, this.messageTypeDialog = MessageType.NON}) : super(key: key); -// -// @override -// State createState() => new FeedbackTypeDialogState(); -// } -// -// class FeedbackTypeDialogState extends State { -// MessageType messageTypeDialog = MessageType.NON; -// -// setMessageDialogType(MessageType messageType) { -// setState(() { -// messageTypeDialog = messageType; -// }); -// } -// -// @override -// void initState() { -// messageTypeDialog = widget.messageTypeDialog; -// -// super.initState(); -// } -// -// Widget build(BuildContext context) { -// return BaseView( -// builder: (_, model, widge) => SimpleDialog( -// title: Text( -// TranslationBase.of(context).messageType, -// textAlign: TextAlign.center, -// ), -// children: [ -// Container( -// // padding: const EdgeInsets.all(10.0), -// child: Column( -// children: [ -// Divider( -// height: 2.5, -// color: Colors.grey[500], -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.NON), -// child: ListTile( -// title: Texts(TranslationBase.of(context).notClassified), -// leading: Radio( -// value: MessageType.NON, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.ComplaintOnAnAppointment), -// child: ListTile( -// title: Texts(TranslationBase.of(context).complainAppo), -// leading: Radio( -// value: MessageType.ComplaintOnAnAppointment, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.ComplaintWithoutAppointment), -// child: ListTile( -// title: Texts(TranslationBase.of(context).complainWithoutAppo), -// leading: Radio( -// value: MessageType.ComplaintWithoutAppointment, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.Question), -// child: ListTile( -// title: Texts(TranslationBase.of(context).question), -// leading: Radio( -// value: MessageType.Question, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.Compliment), -// child: ListTile( -// title: Texts(TranslationBase.of(context).compliment), -// leading: Radio( -// value: MessageType.Compliment, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Row( -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () => setMessageDialogType(MessageType.Suggestion), -// child: ListTile( -// title: Texts(TranslationBase.of(context).suggestion), -// leading: Radio( -// value: MessageType.Suggestion, -// groupValue: messageTypeDialog, -// activeColor: CustomColors.accentColor, -// onChanged: (MessageType value) => setMessageDialogType(value), -// ), -// ), -// ), -// ) -// ], -// ), -// SizedBox( -// height: 5.0, -// ), -// Divider( -// height: 2.5, -// color: Colors.grey[500], -// ), -// SizedBox( -// height: 5, -// ), -// Row( -// // mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// Navigator.pop(context); -// }, -// child: Padding( -// padding: EdgeInsets.all(8.0), -// child: Container( -// child: Center( -// child: Texts( -// TranslationBase.of(context).cancel, -// color: CustomColors.accentColor, -// ), -// ), -// ), -// ), -// ), -// ), -// Container( -// width: 1, -// height: 30, -// color: Colors.grey[500], -// ), -// Expanded( -// flex: 1, -// child: InkWell( -// onTap: () { -// widget.onValueSelected(messageTypeDialog); -// Navigator.pop(context); -// }, -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Center( -// child: Texts( -// TranslationBase.of(context).ok, -// fontWeight: FontWeight.w400, -// )), -// ), -// )), -// ], -// ) -// ], -// ), -// ), -// ], -// ), -// ); -// } -// } +} \ No newline at end of file diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 21160b61..5e15be86 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -388,13 +388,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { ); } - // todo 'sikander' remove useless code - // showDialogs(String message) { - // ConfirmDialog dialog = new ConfirmDialog( - // context: context, confirmMessage: message, okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => {}, cancelFunction: () => {}); - // dialog.showAlertDialog(context); - // } - Future> requestPermissions() async { var permissionResults = [ Permission.location, diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart index 389baf24..877c52fc 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -111,15 +111,6 @@ class AskDoctorPage extends StatelessWidget { ); } - // todo 'sikander' remove this later - String getDoctorSpeciality(List docSpecial) { - String docSpeciality = ""; - docSpecial.forEach((v) { - docSpeciality = docSpeciality + v + "\n"; - }); - return docSpeciality; - } - String getDate(String date) { DateTime dateObj = DateUtil.convertStringToDate(date); return DateUtil.getWeekDay(dateObj.weekday) + diff --git a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart index 7c96dc3e..9eb3e1a5 100644 --- a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart +++ b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart @@ -216,30 +216,6 @@ class _AddWeightPageState extends State { ), ); return; - - // todo 'sikander' remove useless code - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: TranslationBase.of(context).removeMeasure, - okText: TranslationBase.of(context).ok, - cancelText: TranslationBase.of(context).cancel, - okFunction: () async { - ConfirmDialog.closeAlertDialog(context); - - GifLoaderDialogUtils.showMyDialog(context); - widget.model.deleteWeightResult(lineItemNo: widget.lineItemNo).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.model.state == ViewState.ErrorLocal) - AppToast.showErrorToast(message: widget.model.error); - else - Navigator.pop(context); - }).catchError((e) { - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: widget.model.error); - }); - }, - cancelFunction: () => {}); - dialog.showAlertDialog(context); }) ], ), diff --git a/lib/widgets/buttons/defaultButton.dart b/lib/widgets/buttons/defaultButton.dart index 22430242..274ef651 100644 --- a/lib/widgets/buttons/defaultButton.dart +++ b/lib/widgets/buttons/defaultButton.dart @@ -1,5 +1,9 @@ import 'package:flutter/material.dart'; +extension WithContainer on DefaultButton { + Widget get insideContainer => Container(color: Colors.white, padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: this); +} + class DefaultButton extends StatelessWidget { final String text; final VoidCallback onPress; diff --git a/lib/widgets/dialogs/radio_selection_dialog.dart b/lib/widgets/dialogs/radio_selection_dialog.dart index 198e25de..4cbfdcc4 100644 --- a/lib/widgets/dialogs/radio_selection_dialog.dart +++ b/lib/widgets/dialogs/radio_selection_dialog.dart @@ -13,8 +13,9 @@ class RadioSelectionDialog extends StatefulWidget { final Function(int) onValueSelected; final List listData; final int selectedIndex; + final bool isScrollable; - const RadioSelectionDialog({Key key, this.onValueSelected, this.listData, this.selectedIndex}) : super(key: key); + const RadioSelectionDialog({Key key, this.onValueSelected, this.listData, this.selectedIndex, this.isScrollable = false}) : super(key: key); @override State createState() => new RadioSelectionDialogState(); @@ -68,36 +69,41 @@ class RadioSelectionDialogState extends State { TranslationBase.of(context).pleaseSelectFromBelowOptions, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), - ListView.separated( - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - padding: EdgeInsets.only(bottom: 42, top: 10), - itemBuilder: (context, index) { - return Row( - children: [ - SizedBox( - width: 22, - height: 22, - child: Radio( - value: widget.listData[index].value, - groupValue: selectedIndex, - onChanged: (value) { - setState(() { - selectedIndex = value; - }); - }, + SizedBox(height: widget.isScrollable ? 12 : 0), + SizedBox( + height: widget.isScrollable ? MediaQuery.of(context).size.height * .4 : null, + child: ListView.separated( + physics: widget.isScrollable ? BouncingScrollPhysics() : NeverScrollableScrollPhysics(), + shrinkWrap: !widget.isScrollable, + padding: EdgeInsets.only(bottom: widget.isScrollable ? 21 : 42, top: 10), + itemBuilder: (context, index) { + return Row( + children: [ + SizedBox( + width: 22, + height: 22, + child: Radio( + value: widget.listData[index].value, + groupValue: selectedIndex, + onChanged: (value) { + setState(() { + selectedIndex = value; + }); + }, + ), ), - ), - SizedBox(width: 8), - Text( - widget.listData[index].title, - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.56), - ), - ], - ); - }, - separatorBuilder: (context, index) => SizedBox(height: 10), - itemCount: widget.listData.length), + SizedBox(width: 8), + Text( + widget.listData[index].title, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.56), + ), + ], + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 10), + itemCount: widget.listData.length), + ), + SizedBox(height: widget.isScrollable ? 12 : 0), Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/otp/sms-popup.dart index 12fb9d3e..74e95e1d 100644 --- a/lib/widgets/otp/sms-popup.dart +++ b/lib/widgets/otp/sms-popup.dart @@ -225,34 +225,6 @@ class SMSOTP { }); } - - // todo 'sikander' remove useless code - // static void showLoadingDialog(BuildContext context, bool _loading) async { - // _context = context; - // //setSignature(); - // if (_loading == false) { - // Navigator.of(context).pop(); - // return; - // } - // _loading = true; - // await showDialog( - // context: _context, - // barrierDismissible: false, - // builder: (BuildContext context) { - // return SimpleDialog( - // elevation: 0.0, - // backgroundColor: Colors.transparent, - // children: [ - // Center( - // child: CircularProgressIndicator( - // valueColor: AlwaysStoppedAnimation(Colors.black), - // ), - // ) - // ], - // ); - // }); - // } - static void hideSMSBox(context) { Navigator.pop(context); } From ebb4c026c649c5086bb1c40127543f6d9b43afd4 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 27 Oct 2021 12:49:19 +0300 Subject: [PATCH 32/60] improvements --- .../NewHomeHealthCare/new_home_health_care_page.dart | 6 ++---- lib/widgets/drawer/app_drawer_widget.dart | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart index 66032f9d..75c68127 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart @@ -158,9 +158,7 @@ class _NewHomeHealthCarePageState extends State with Tick widget.model.hhcAllOrderDetail.length, (index) => Container( child: Texts( - projectViewModel.isArabic - ? widget.model.hhcAllOrderDetail[index].descriptionN - : widget.model.hhcAllOrderDetail[index].description.capitalize(), + projectViewModel.isArabic ? widget.model.hhcAllOrderDetail[index].descriptionN : widget.model.hhcAllOrderDetail[index].description.capitalize(), fontSize: 13, bold: false, ), @@ -178,7 +176,7 @@ class _NewHomeHealthCarePageState extends State with Tick crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.model.pendingOrder.createdOn)), + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.model.pendingOrder.created)), style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), ), SizedBox(height: 12), diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index a66d5850..affcb02a 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; @@ -36,7 +34,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:in_app_review/in_app_review.dart'; import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; import '../../config/size_config.dart'; import '../../locator.dart'; From ddf764897a4a5ba0f09e0db916798c482f2e797b Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 12:55:38 +0300 Subject: [PATCH 33/60] Pharmacy Payment method design fix, Blood Donation fix --- .../service/blood/blood_details_servies.dart | 2 +- .../medical/my_balance_view_model.dart | 3 + .../pharmacyModule/OrderPreviewViewModel.dart | 2 +- .../health_converter/blood_cholesterol.dart | 2 - .../​ health_calculators.dart | 15 +- lib/pages/Blood/blood_donation.dart | 268 +++++------------- .../ChildVaccines/new/child_vaccine_page.dart | 2 +- lib/pages/ToDoList/payment_method_select.dart | 73 ----- lib/pages/landing/widgets/services_view.dart | 2 +- .../smart_watch_instructions.dart | 3 +- .../screens/cart-order-preview.dart | 0 .../select_payment_option_widget.dart | 42 +-- .../screens/payment-method-select-page.dart | 252 +++++++++------- 13 files changed, 249 insertions(+), 417 deletions(-) delete mode 100644 lib/pages/pharmacies/screens/cart-order-preview.dart diff --git a/lib/core/service/blood/blood_details_servies.dart b/lib/core/service/blood/blood_details_servies.dart index 644d96d9..589b8dda 100644 --- a/lib/core/service/blood/blood_details_servies.dart +++ b/lib/core/service/blood/blood_details_servies.dart @@ -22,7 +22,7 @@ class BloodDetailsService extends BaseService{ BloodModelList.add(List_BloodGroupDetailsModel.fromJson(vital)); }); }, onFailure: (String error, int statusCode) { - hasError = true; + // hasError = true; super.error = error; }, body: body); } diff --git a/lib/core/viewModels/medical/my_balance_view_model.dart b/lib/core/viewModels/medical/my_balance_view_model.dart index ce9f35fa..9413b0ed 100644 --- a/lib/core/viewModels/medical/my_balance_view_model.dart +++ b/lib/core/viewModels/medical/my_balance_view_model.dart @@ -52,6 +52,9 @@ class MyBalanceViewModel extends BaseViewModel { PatientInfoAndMobileNumber get patientInfoAndMobileNumber => _myBalanceService.patientInfoAndMobileNumber; + List get bloodModelList => + _bloodDetailsService.BloodModelList; + String get logInTokenID => _myBalanceService.logInTokenID; String get verificationCode => _myBalanceService.verificationCode; diff --git a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart index f2f87712..e64ab20c 100644 --- a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart @@ -228,4 +228,4 @@ class OrderPreviewViewModel extends BaseViewModel { } } -enum PaymentOption { meda, sadad, visa, mastercard, installments } +enum PaymentOption { meda, sadad, visa, mastercard, installments, applepay } diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart index faa3af72..5e584602 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart @@ -77,7 +77,6 @@ class _BloodCholesterolState extends State { width: 350.0, child: Text( TranslationBase.of(context).convertCholesterolStatement, - //textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0), ), ), @@ -90,7 +89,6 @@ class _BloodCholesterolState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Column( - //crossAxisAlignment: CrossAxisAlignment.end, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0), diff --git a/lib/pages/AlHabibMedicalService/​ health_calculators.dart b/lib/pages/AlHabibMedicalService/​ health_calculators.dart index 5dce5b15..de4e3a48 100644 --- a/lib/pages/AlHabibMedicalService/​ health_calculators.dart +++ b/lib/pages/AlHabibMedicalService/​ health_calculators.dart @@ -50,18 +50,23 @@ class _HealthCalculatorsState extends State with SingleTicker children: [ TabBar( controller: _tabController, - isScrollable: true, - indicatorWeight: 4.0, - indicatorColor: Colors.red, - labelColor: Theme.of(context).buttonColor, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), - unselectedLabelColor: Colors.grey, labelStyle: TextStyle( fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: -0.48, ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), tabs: [ Container( width: MediaQuery.of(context).size.width * 0.35, diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index e3888240..3be9b765 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; + //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; @@ -13,6 +14,7 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStat import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectCiteisDialog.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -25,11 +27,8 @@ import 'package:flutter/material.dart'; import 'package:giffy_dialog/giffy_dialog.dart'; import 'package:provider/provider.dart'; -import 'dialogs/SelectBeneficiaryDialog.dart'; import 'dialogs/SelectBloodDialog.dart'; import 'dialogs/SelectGenderDialog.dart'; -import 'dialogs/SelectPatientFamilyDialog.dart'; -import 'dialogs/SelectPatientInfoDialog.dart'; enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } enum Gender { Male, Female, NON } @@ -79,7 +78,10 @@ class _BloodDonationPageState extends State { projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.getCities(), //model.getHospitals(), + onModelReady: (model) { + model.getCities(); + model.getBlood(); + }, builder: (_, model, w) => AppScaffold( isShowAppBar: true, showNewAppBar: true, @@ -95,9 +97,7 @@ class _BloodDonationPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).bloodDEnterDesc - ), + Texts(TranslationBase.of(context).bloodDEnterDesc), SizedBox( height: 12, ), @@ -111,7 +111,7 @@ class _BloodDonationPageState extends State { decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts(getHospitalName(projectProvider, context), color: Colors.black), Icon(Icons.arrow_drop_down)], + children: [Texts(getHospitalName(projectProvider, context, model), color: Colors.black), Icon(Icons.arrow_drop_down)], ), ), ), @@ -119,7 +119,6 @@ class _BloodDonationPageState extends State { height: 12, ), InkWell( - //======Gender======== onTap: () => confirmSelectGenderDialog(), child: Container( padding: EdgeInsets.all(12), @@ -128,10 +127,7 @@ class _BloodDonationPageState extends State { decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getGender(context), color: Colors.black), - Icon(Icons.arrow_drop_down) - ], + children: [Texts(getGender(context), color: Colors.black), Icon(Icons.arrow_drop_down)], ), ), ), @@ -139,7 +135,6 @@ class _BloodDonationPageState extends State { height: 12, ), InkWell( - //======Gender======== onTap: () => confirmSelectBloodDialog(), child: Container( padding: EdgeInsets.all(12), @@ -148,7 +143,7 @@ class _BloodDonationPageState extends State { decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts(getBlood(), color: Colors.black), Icon(Icons.arrow_drop_down)], + children: [Texts(getBlood(model), color: Colors.black), Icon(Icons.arrow_drop_down)], ), ), ), @@ -241,45 +236,31 @@ class _BloodDonationPageState extends State { width: double.infinity, color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(20), - child: DefaultButton(TranslationBase.of(context).save, () async { - if (_selectedHospital == null) { - AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); - return; - } - bloodDetails.city = projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; - bloodDetails.cityCode = _selectedHospital.iD.toString(); - bloodDetails.gender = gender == Gender.Male ? 1 : 2; - await model.updateBloodGroup(bloodDetails); - if (model.state == ViewState.Idle) { - AppToast.showSuccessToast(message: model.updatedRegisterBloodMessage); - } else { - AppToast.showErrorToast(message: model.error); - } - }), + child: DefaultButton( + TranslationBase.of(context).save, + checkedValue + ? () async { + if (_selectedHospital == null) { + AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); + return; + } + bloodDetails.city = projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; + bloodDetails.cityCode = _selectedHospital.iD.toString(); + bloodDetails.gender = gender == Gender.Male ? 1 : 2; + await model.updateBloodGroup(bloodDetails); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast(message: model.updatedRegisterBloodMessage); + } else { + AppToast.showErrorToast(message: model.error); + } + } + : null, + disabledColor: CustomColors.grey2, + ), )), ); } - void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { - showDialog( - context: context, - child: SelectBeneficiaryDialog( - beneficiaryType: beneficiaryType, - onValueSelected: (value) { - setState(() { - if (value == BeneficiaryType.MyAccount) { - _fileTextController.text = model.user.patientID.toString(); - advanceModel.depositorName = model.user.firstName + " " + model.user.lastName; - } else - _fileTextController.text = ""; - - beneficiaryType = value; - }); - }, - ), - ); - } - void confirmSelectBloodDialog() { showDialog( context: context, @@ -289,48 +270,22 @@ class _BloodDonationPageState extends State { setState(() { if (value == Blood.Oplus) { bloodDetails.bloodGroup = "O+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.Ominus) { - // _fileTextController.text = model.user.patientID.toString(); bloodDetails.bloodGroup = "O-"; - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.ABplus) { bloodDetails.bloodGroup = "AB+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.ABminus) { bloodDetails.bloodGroup = "AB-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.Aplus) { bloodDetails.bloodGroup = "A+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.Aminus) { bloodDetails.bloodGroup = "A-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.Bplus) { bloodDetails.bloodGroup = "B+"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else if (value == Blood.Bminus) { bloodDetails.bloodGroup = "B-"; - // _fileTextController.text = model.user.patientID.toString(); - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; } else _fileTextController.text = ""; - - // beneficiaryType = value; blood = value; }); }, @@ -346,17 +301,10 @@ class _BloodDonationPageState extends State { onValueSelected: (value) { setState(() { if (value == Gender.Male) { - // _fileTextController.text = model.user.patientID.toString(); bloodDetails.patientType = 1; - // advanceModel.depositorName = - // model.user.firstName + " " + model.user.lastName; - } else - // _fileTextController.text = ""; - { + } else { bloodDetails.gender = 2; } - - // beneficiaryType = value; gender = value; }); }, @@ -364,7 +312,6 @@ class _BloodDonationPageState extends State { ); } -//void confirmSelectHospitalDialog(List hospitals) { void confirmSelectHospitalDialog(List hospitals) { showDialog( context: context, @@ -380,55 +327,6 @@ class _BloodDonationPageState extends State { ); } - void confirmSelectPatientDialog(List patientInfoList) { - showDialog( - context: context, - child: SelectPatientInfoDialog( - patientInfoList: patientInfoList, - selectedPatientInfo: _selectedPatientInfo, - onValueSelected: (value) { - setState(() { - advanceModel.depositorName = value.fullName; - _selectedPatientInfo = value; - }); - }, - ), - ); - } - - void confirmSelectFamilyDialog(List getAllSharedRecordsByStatusList) { - showDialog( - context: context, - child: SelectPatientFamilyDialog( - getAllSharedRecordsByStatusList: getAllSharedRecordsByStatusList, - selectedPatientFamily: selectedPatientFamily, - onValueSelected: (value) { - setState(() { - selectedPatientFamily = value; - _fileTextController.text = selectedPatientFamily.patientID.toString(); - advanceModel.depositorName = value.patientName; - }); - }, - ), - ); - } - - String getBeneficiaryType() { - switch (beneficiaryType) { - case BeneficiaryType.MyAccount: - return TranslationBase.of(context).myAccount; - case BeneficiaryType.MyFamilyFiles: - return TranslationBase.of(context).myFamilyFiles; - break; - case BeneficiaryType.OtherAccount: - return TranslationBase.of(context).otherAccount; - break; - case BeneficiaryType.NON: - return TranslationBase.of(context).selectBeneficiary; - } - return TranslationBase.of(context).selectBeneficiary; - } - String getGender(BuildContext context) { switch (gender) { case Gender.Male: @@ -436,62 +334,60 @@ class _BloodDonationPageState extends State { case Gender.Female: return TranslationBase.of(context).female; break; - case Gender.NON: return TranslationBase.of(context).selectGender; } return TranslationBase.of(context).selectGender; } - String getBlood() { - switch (blood) { - case Blood.Oplus: - return "O+"; - break; - case Blood.Ominus: - return "O-"; - break; - case Blood.ABplus: - return "AB+"; - break; - case Blood.ABminus: - return "AB-"; - break; - case Blood.Aplus: - return "A+"; - break; - case Blood.Aminus: - return "A-"; - break; - case Blood.Bplus: - return "B-"; - break; - case Blood.Bminus: - return "B-"; - break; - case Blood.Bplus: - return "B+"; - break; - - case Blood.NON: - return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; + String getBlood(MyBalanceViewModel model) { + if (model.bloodModelList.length > 0) { + return model.bloodModelList[0].bloodGroup; + } else { + switch (blood) { + case Blood.Oplus: + return "O+"; + break; + case Blood.Ominus: + return "O-"; + break; + case Blood.ABplus: + return "AB+"; + break; + case Blood.ABminus: + return "AB-"; + break; + case Blood.Aplus: + return "A+"; + break; + case Blood.Aminus: + return "A-"; + break; + case Blood.Bplus: + return "B-"; + break; + case Blood.Bminus: + return "B-"; + break; + case Blood.Bplus: + return "B+"; + break; + case Blood.NON: + return "Select Blood Type"; + } } - return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; + return "Select Blood Type"; } - String getHospitalName(ProjectViewModel projectProvider, BuildContext context) { - if (_selectedHospital != null) - return projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; - else - return TranslationBase.of(context).selectCity; - // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; - } - - String getPatientName() { - if (_selectedPatientInfo != null) - return _selectedPatientInfo.fullName; - else - return TranslationBase.of(context).selectPatientName; + String getHospitalName(ProjectViewModel projectProvider, BuildContext context, MyBalanceViewModel model) { + if (model.bloodModelList.length > 0) { + return model.bloodModelList[0].city; + } else { + if (_selectedHospital != null) + return projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; + else + return TranslationBase.of(context).selectCity; + } } getAuthUser() async { @@ -502,14 +398,4 @@ class _BloodDonationPageState extends State { }); } } - - String getFamilyMembersName() { - if (selectedPatientFamily != null) - return selectedPatientFamily.patientName; - else - return TranslationBase.of(context).selectFamilyPatientName; - } - -//================ - } diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index 81f83798..f847352f 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -94,7 +94,7 @@ class _ChildPageState extends State with SingleTickerProviderS ), ), Text( - model.babyInformationModelList[index].gender == 1 ? TranslationBase.of(context).female : TranslationBase.of(context).male, + model.babyInformationModelList[index].genderDescription, style: TextStyle( fontSize: 11, color: selectedColor, diff --git a/lib/pages/ToDoList/payment_method_select.dart b/lib/pages/ToDoList/payment_method_select.dart index 542c1c23..1cccf517 100644 --- a/lib/pages/ToDoList/payment_method_select.dart +++ b/lib/pages/ToDoList/payment_method_select.dart @@ -5,7 +5,6 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class PaymentMethod extends StatefulWidget { Function onSelectedMethod; @@ -37,7 +36,6 @@ class _PaymentMethodState extends State { children: [ Container( margin: EdgeInsets.fromLTRB(4, 15.0, 4, 0.0), - child: Text(TranslationBase.of(context).selectPaymentOption, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)), ), Container( @@ -119,16 +117,6 @@ class _PaymentMethodState extends State { width: 60, child: Image.asset("assets/images/new/payment/visa.png"), ), - // mWidth(12), - // Text( - // "VISA", - // style: TextStyle( - // color: Colors.black, - // fontSize: 14, - // fontWeight: FontWeight.bold, - // ), - // ) - // , mFlex(1), if (selectedPaymentMethod == "VISA") Container( @@ -178,15 +166,6 @@ class _PaymentMethodState extends State { width: 60, child: Image.asset("assets/images/new/payment/Mastercard.png"), ), - // mWidth(12), - // Text( - // "MasterCard", - // style: TextStyle( - // color: Colors.black, - // fontSize: 14, - // fontWeight: FontWeight.bold, - // ), - // ), mFlex(1), if (selectedPaymentMethod == "MASTERCARD") Container( @@ -236,15 +215,6 @@ class _PaymentMethodState extends State { width: 60, child: Image.asset("assets/images/new/payment/installments.png"), ), - // mWidth(12), - // Text( - // "Installments", - // style: TextStyle( - // color: Colors.black, - // fontSize: 14, - // fontWeight: FontWeight.bold, - // ), - // ), mFlex(1), if (selectedPaymentMethod == "Installment") Container( @@ -295,15 +265,6 @@ class _PaymentMethodState extends State { width: 60, child: Image.asset("assets/images/new/payment/Apple_Pay.png"), ), - // mWidth(12), - // Text( - // "Apple Pay", - // style: TextStyle( - // color: Colors.black, - // fontSize: 14, - // fontWeight: FontWeight.bold, - // ), - // ), mFlex(1), if (selectedPaymentMethod == "ApplePay") Container( @@ -323,40 +284,6 @@ class _PaymentMethodState extends State { ), ), ) - // Container( - // margin: EdgeInsets.only(top: 25.0), - // child: Flex( - // direction: Axis.horizontal, - // children: [ - // Expanded( - // child: Container( - // child: InkWell( - // onTap: () { - // updateSelectedPaymentMethod("ApplePay"); - // }, - // child: Card( - // elevation: 3.0, - // margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - // color: Colors.white, - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(10), - // side: selectedPaymentMethod == "ApplePay" ? BorderSide(color: Colors.green, width: 5.0) : BorderSide(color: Colors.transparent, width: 0.0), - // ), - // child: Container( - // height: 120.0, - // padding: EdgeInsets.all(20.0), - // child: SvgPicture.asset("assets/images/new-design/applepay.svg"), - // ), - // ), - // ), - // ), - // ), - // Expanded( - // child: Container(), - // ), - // ], - // ), - // ) : Container(), SizedBox( height: 150.0, diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index 37e7cd74..b233c6a7 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -107,7 +107,7 @@ class ServicesView extends StatelessWidget { FadePage(page: ChildInitialPage()), ); } else if (index == 15) { - Navigator.pop(context); + // Navigator.pop(context); LandingPage.shared.switchToDoFromHMGServices(); } else if (index == 16) { Navigator.push( diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index 7cc6ab01..4fc233db 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -62,10 +62,9 @@ class _SmartWatchInstructionsState extends State { mainAxisSize: MainAxisSize.min, children: [ Flexible( - // margin: EdgeInsets.only(top: 10.0), child: CarouselSlider( carouselController: buttonCarouselController, - options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.65), + options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.9), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { diff --git a/lib/pages/pharmacies/screens/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-order-preview.dart deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart b/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart index 9234bb38..6e506458 100644 --- a/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart +++ b/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart @@ -1,26 +1,10 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; -import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/payment_bottom_widget.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/payment-method-select-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderPreviewItem.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class SelectPaymentOptionWidget extends StatefulWidget { final OrderPreviewViewModel model; @@ -28,24 +12,21 @@ class SelectPaymentOptionWidget extends StatefulWidget { SelectPaymentOptionWidget(this.model); @override - _SelectPaymentOptionWidgetState createState() => - _SelectPaymentOptionWidgetState(); + _SelectPaymentOptionWidgetState createState() => _SelectPaymentOptionWidgetState(); } class _SelectPaymentOptionWidgetState extends State { PaymentOption paymentOption; _navigateToPaymentOption() { - Navigator.push(context, FadePage(page: PaymentMethodSelectPage())) - .then((result) => { - setState(() { - if (result != null) { - paymentOption = result; - widget.model.paymentCheckoutData.paymentOption = - paymentOption; - } - }) - }); + Navigator.push(context, FadePage(page: PaymentMethodSelectPage())).then((result) => { + setState(() { + if (result != null) { + paymentOption = result; + widget.model.paymentCheckoutData.paymentOption = paymentOption; + } + }) + }); } @override @@ -75,8 +56,7 @@ class _SelectPaymentOptionWidgetState extends State { ), Expanded( child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), child: Texts( TranslationBase.of(context).selectPaymentOption, fontSize: 14, diff --git a/lib/pages/pharmacies/screens/payment-method-select-page.dart b/lib/pages/pharmacies/screens/payment-method-select-page.dart index 8cdbaf3c..92065102 100644 --- a/lib/pages/pharmacies/screens/payment-method-select-page.dart +++ b/lib/pages/pharmacies/screens/payment-method-select-page.dart @@ -1,14 +1,16 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; class PaymentMethodSelectPage extends StatefulWidget { @override - _PaymentMethodSelectPageState createState() => - _PaymentMethodSelectPageState(); + _PaymentMethodSelectPageState createState() => _PaymentMethodSelectPageState(); } class _PaymentMethodSelectPageState extends State { @@ -20,8 +22,9 @@ class _PaymentMethodSelectPageState extends State { double cardWidth = screenSize.width / 2 - 32; return AppScaffold( - title: "Payment method", + appBarTitle: TranslationBase.of(context).paymentMethod, isShowAppBar: true, + isPharmacy: true, isShowDecPage: false, body: Container( width: double.infinity, @@ -30,72 +33,65 @@ class _PaymentMethodSelectPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( - child: Texts( + child: Text( TranslationBase.of(context).selectPaymentOption, - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.black, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.black, + ), ), ), Container( margin: EdgeInsets.symmetric(horizontal: 0, vertical: 16), child: Column( children: [ - Row( - children: [ - PaymentMethodCard( - cardWidth, - selectedPaymentOption, - PaymentOption.meda, - () => { - setState(() { - selectedPaymentOption = PaymentOption.meda; - }) - }), - PaymentMethodCard( - cardWidth, - selectedPaymentOption, - PaymentOption.sadad, - () => { - setState(() { - selectedPaymentOption = PaymentOption.sadad; - }) - }), - ], - ), - Row( - children: [ - PaymentMethodCard( - cardWidth, - selectedPaymentOption, - PaymentOption.visa, - () => { - setState(() { - selectedPaymentOption = PaymentOption.visa; - }) - }), - PaymentMethodCard( - cardWidth, - selectedPaymentOption, - PaymentOption.mastercard, - () => { - setState(() { - selectedPaymentOption = - PaymentOption.mastercard; - }) - }), - ], - ), PaymentMethodCard( - (cardWidth * 2 + 32), + cardWidth, + selectedPaymentOption, + PaymentOption.meda, + () => { + setState(() { + selectedPaymentOption = PaymentOption.meda; + }) + }), + PaymentMethodCard( + cardWidth, + selectedPaymentOption, + PaymentOption.visa, + () => { + setState(() { + selectedPaymentOption = PaymentOption.visa; + }) + }), + PaymentMethodCard( + cardWidth, + selectedPaymentOption, + PaymentOption.mastercard, + () => { + setState(() { + selectedPaymentOption = PaymentOption.mastercard; + }) + }), + PaymentMethodCard( + cardWidth, selectedPaymentOption, PaymentOption.installments, () => { setState(() { - selectedPaymentOption = - PaymentOption.installments; + selectedPaymentOption = PaymentOption.installments; }) }), + if (Platform.isIOS) + PaymentMethodCard( + cardWidth, + selectedPaymentOption, + PaymentOption.applepay, + () => { + setState(() { + selectedPaymentOption = PaymentOption.applepay; + }) + }), ], ), ), @@ -103,18 +99,12 @@ class _PaymentMethodSelectPageState extends State { ), ), bottomSheet: Container( - height: screenSize.height * 0.08, - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: BorderedButton( + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 20), + child: DefaultButton( TranslationBase.of(context).next, - backgroundColor: Color(0xff5AB154), - textColor: Colors.white, - fontSize: 16, - hPadding: 8, - vPadding: 12, - handler: selectedPaymentOption != null - ? () => {Navigator.pop(context, selectedPaymentOption)} - : null, + selectedPaymentOption != null ? () => {Navigator.pop(context, selectedPaymentOption)} : null, + color: Color(0xff5AB154), ), ), ); @@ -127,61 +117,102 @@ class PaymentMethodCard extends StatelessWidget { final PaymentOption paymentOption; final Function selectMethod; - PaymentMethodCard(this.cardWidth, this.selectedPaymentOption, - this.paymentOption, this.selectMethod); + PaymentMethodCard(this.cardWidth, this.selectedPaymentOption, this.paymentOption, this.selectMethod); @override Widget build(BuildContext context) { bool isSelected = false; - if (selectedPaymentOption != null && - selectedPaymentOption == paymentOption) { + if (selectedPaymentOption != null && selectedPaymentOption == paymentOption) { isSelected = true; } - return InkWell( - onTap: selectMethod, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 2, vertical: 0), - child: Stack( - children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8), - margin: EdgeInsets.symmetric(horizontal: 14, vertical: 8), - decoration: new BoxDecoration( - color: Colors.grey.shade100, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.fromBorderSide(BorderSide( - color: isSelected ? Color(0xff20BC11) : Colors.grey.shade300, - width: 0.8, - )), - ), - width: cardWidth, - child: Image.asset( - getPaymentOptionImage(paymentOption), - fit: BoxFit.cover, - ), - ), - if (isSelected) - Positioned( - right: 1, - child: Icon( - Icons.check_circle, - color: Color(0xff20BC11), - size: 30, + return Container( + width: MediaQuery.of(context).size.width * 0.99, + child: InkWell( + onTap: selectMethod, + child: Card( + elevation: 0.0, + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: isSelected ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + children: [ + Container( + width: 24, + height: 24, + decoration: containerColorRadiusBorderWidth(isSelected ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - ), - ], + mWidth(12), + Container( + height: 70.0, + width: 70.0, + child: Image.asset(getPaymentOptionImage(paymentOption)), + ), + mFlex(1), + if (isSelected) + Container( + decoration: containerRadius(CustomColors.green, 200), + padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), + child: Text( + TranslationBase.of(context).paymentSelected, + style: TextStyle( + color: Colors.white, + fontSize: 11, + ), + ), + ), + ], + ), + ), ), + // Container( + // margin: EdgeInsets.symmetric(horizontal: 2, vertical: 0), + // child: Stack( + // children: [ + // Container( + // padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8), + // margin: EdgeInsets.symmetric(horizontal: 14, vertical: 8), + // decoration: new BoxDecoration( + // color: Colors.grey.shade100, + // shape: BoxShape.rectangle, + // borderRadius: BorderRadius.circular(8), + // border: Border.fromBorderSide(BorderSide( + // color: isSelected ? Color(0xff20BC11) : Colors.grey.shade300, + // width: 0.8, + // )), + // ), + // width: cardWidth, + // child: Image.asset( + // getPaymentOptionImage(paymentOption), + // fit: BoxFit.cover, + // ), + // ), + // if (isSelected) + // Positioned( + // right: 1, + // child: Icon( + // Icons.check_circle, + // color: Color(0xff20BC11), + // size: 30, + // ), + // ), + // ], + // ), + // ), ), ); } String getPaymentOptionImage(PaymentOption paymentOption) { - String assetFile = "assets/images/pharmacy_module/payment/"; + String assetFile = "assets/images/new/payment/"; switch (paymentOption.index) { case 0: - return "${assetFile}mada.png"; + return "${assetFile}Mada.png"; break; case 1: return "${assetFile}sadad.png"; @@ -190,10 +221,13 @@ class PaymentMethodCard extends StatelessWidget { return "${assetFile}visa.png"; break; case 3: - return "${assetFile}mastercard.png"; + return "${assetFile}Mastercard.png"; break; case 4: - return "${assetFile}installment.png"; + return "${assetFile}installments.png"; + break; + case 5: + return "${assetFile}Apple_Pay.png"; break; default: return ""; From df7d8a8603f232db58d42da403cfc7589791ee0b Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 13:12:42 +0300 Subject: [PATCH 34/60] Blood donation fixes --- .../medical/my_balance_view_model.dart | 2 +- lib/pages/Blood/blood_donation.dart | 157 ++++-------------- 2 files changed, 34 insertions(+), 125 deletions(-) diff --git a/lib/core/viewModels/medical/my_balance_view_model.dart b/lib/core/viewModels/medical/my_balance_view_model.dart index 9413b0ed..a92b6e16 100644 --- a/lib/core/viewModels/medical/my_balance_view_model.dart +++ b/lib/core/viewModels/medical/my_balance_view_model.dart @@ -32,7 +32,7 @@ class MyBalanceViewModel extends BaseViewModel { _bloodDonationService.CitiesModelList; BloodDetailsService _bloodDetailsService = locator(); - List get BloodDetailsModelList => + List get bloodDetailsModelList => _bloodDetailsService .BloodModelList; //_bloodDonationService.CitiesModelList; diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index ffb7e1ee..be58b644 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -1,4 +1,3 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; @@ -14,6 +13,7 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStat import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -26,10 +26,6 @@ import 'package:flutter/material.dart'; import 'package:giffy_dialog/giffy_dialog.dart'; import 'package:provider/provider.dart'; -import 'dialogs/SelectBeneficiaryDialog.dart'; -import 'dialogs/SelectPatientFamilyDialog.dart'; -import 'dialogs/SelectPatientInfoDialog.dart'; - enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } enum Gender { Male, Female, NON } enum Blood { Oplus, Ominus, Aplus, Aminus, Bplus, Bminus, ABplus, ABminus, NON } @@ -73,7 +69,7 @@ class _BloodDonationPageState extends State { ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/blood/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/blood/ar/0.png'), ); WidgetsBinding.instance.addPostFrameCallback((_) { - if (projectProvider.isLogin) getAuthUser(); + if (projectProvider.isLogin) authUser = projectProvider.user; }); super.initState(); } @@ -83,7 +79,10 @@ class _BloodDonationPageState extends State { projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.getCities(), //model.getHospitals(), + onModelReady: (model) { + model.getCities(); + model.getBlood(); + }, builder: (_, model, w) => AppScaffold( isShowAppBar: true, showNewAppBar: true, @@ -109,11 +108,11 @@ class _BloodDonationPageState extends State { SizedBox(height: 12), CommonDropDownView( TranslationBase.of(context).city, - model.CitiesModelList.isNotEmpty - ? projectProvider.isArabic + model.bloodModelList.isNotEmpty + ? model.bloodModelList[0].city + : projectProvider.isArabic ? model.CitiesModelList[_selectedHospitalIndex].descriptionN - : model.CitiesModelList[_selectedHospitalIndex].description - : "", () { + : model.CitiesModelList[_selectedHospitalIndex].description, () { List list = [ for (int i = 0; i < model.CitiesModelList.length; i++) RadioSelectionDialogModel(projectProvider.isArabic ? model.CitiesModelList[i].descriptionN : model.CitiesModelList[i].description, i), @@ -152,7 +151,7 @@ class _BloodDonationPageState extends State { ); }).withBorderedContainer, SizedBox(height: 12), - CommonDropDownView(TranslationBase.of(context).bloodType, getBlood(_selectedBloodTypeIndex), () { + CommonDropDownView(TranslationBase.of(context).bloodType, model.bloodModelList.isNotEmpty ? model.bloodModelList[0].bloodGroup : getBlood(_selectedBloodTypeIndex), () { List list = [ RadioSelectionDialogModel("O+", 0), RadioSelectionDialogModel("O-", 1), @@ -253,97 +252,34 @@ class _BloodDonationPageState extends State { ), ), ), - DefaultButton(TranslationBase.of(context).save, () async { - if (_selectedHospital == null) { - AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); - return; - } - bloodDetails.city = projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; - bloodDetails.cityCode = _selectedHospital.iD.toString(); - bloodDetails.gender = _selectedGenderIndex; - bloodDetails.bloodGroup = getBlood(_selectedBloodTypeIndex); - await model.updateBloodGroup(bloodDetails); - if (model.state == ViewState.Idle) { - AppToast.showSuccessToast(message: model.updatedRegisterBloodMessage); - } else { - AppToast.showErrorToast(message: model.error); - } - }).insideContainer + DefaultButton( + TranslationBase.of(context).save, + checkedValue + ? () async { + if (_selectedHospital == null) { + AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); + return; + } + bloodDetails.city = projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; + bloodDetails.cityCode = _selectedHospital.iD.toString(); + bloodDetails.gender = _selectedGenderIndex; + bloodDetails.bloodGroup = getBlood(_selectedBloodTypeIndex); + await model.updateBloodGroup(bloodDetails); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast(message: model.updatedRegisterBloodMessage); + } else { + AppToast.showErrorToast(message: model.error); + } + } + : null, + disabledColor: CustomColors.grey2, + ).insideContainer ], ), ), ); } - void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { - showDialog( - context: context, - child: SelectBeneficiaryDialog( - beneficiaryType: beneficiaryType, - onValueSelected: (value) { - setState(() { - if (value == BeneficiaryType.MyAccount) { - _fileTextController.text = model.user.patientID.toString(); - advanceModel.depositorName = model.user.firstName + " " + model.user.lastName; - } else - _fileTextController.text = ""; - - beneficiaryType = value; - }); - }, - ), - ); - } - - void confirmSelectPatientDialog(List patientInfoList) { - showDialog( - context: context, - child: SelectPatientInfoDialog( - patientInfoList: patientInfoList, - selectedPatientInfo: _selectedPatientInfo, - onValueSelected: (value) { - setState(() { - advanceModel.depositorName = value.fullName; - _selectedPatientInfo = value; - }); - }, - ), - ); - } - - void confirmSelectFamilyDialog(List getAllSharedRecordsByStatusList) { - showDialog( - context: context, - child: SelectPatientFamilyDialog( - getAllSharedRecordsByStatusList: getAllSharedRecordsByStatusList, - selectedPatientFamily: selectedPatientFamily, - onValueSelected: (value) { - setState(() { - selectedPatientFamily = value; - _fileTextController.text = selectedPatientFamily.patientID.toString(); - advanceModel.depositorName = value.patientName; - }); - }, - ), - ); - } - - String getBeneficiaryType() { - switch (beneficiaryType) { - case BeneficiaryType.MyAccount: - return TranslationBase.of(context).myAccount; - case BeneficiaryType.MyFamilyFiles: - return TranslationBase.of(context).myFamilyFiles; - break; - case BeneficiaryType.OtherAccount: - return TranslationBase.of(context).otherAccount; - break; - case BeneficiaryType.NON: - return TranslationBase.of(context).selectBeneficiary; - } - return TranslationBase.of(context).selectBeneficiary; - } - String getBlood(int index) { switch (index) { case 0: @@ -384,32 +320,5 @@ class _BloodDonationPageState extends State { return projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; else return TranslationBase.of(context).selectCity; - // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; } - - String getPatientName() { - if (_selectedPatientInfo != null) - return _selectedPatientInfo.fullName; - else - return TranslationBase.of(context).selectPatientName; - } - - getAuthUser() async { - if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); - setState(() { - authUser = data; - }); - } - } - - String getFamilyMembersName() { - if (selectedPatientFamily != null) - return selectedPatientFamily.patientName; - else - return TranslationBase.of(context).selectFamilyPatientName; - } - -//================ - } From b53d9129968c50188fc4e0067e6a85bbfc2edaf8 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 13:44:35 +0300 Subject: [PATCH 35/60] Fixes & updates --- .../components/SearchByDoctor.dart | 2 +- .../ChildVaccines/new/child_vaccine_page.dart | 2 +- .../OfferAndPackagesCartPage.dart | 5 ++++- .../medical/LabResult/LabResultWidget.dart | 20 ++++++++++++------- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index dde431e6..829ac0e2 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -193,7 +193,7 @@ class _SearchByDoctorState extends State { TextField( enabled: isEnable, scrollPadding: EdgeInsets.zero, - keyboardType: TextInputType.number, + keyboardType: TextInputType.text, controller: _controller, onChanged: (value) => {_onDocTextChanged(value)}, style: TextStyle( diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index f847352f..5f55401e 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -60,7 +60,7 @@ class _ChildPageState extends State with SingleTickerProviderS borderRadius: BorderRadius.all(Radius.circular(12)), color: Colors.white, gradient: LinearGradient( - colors: model.babyInformationModelList[index].gender == 1 + colors: model.babyInformationModelList[index].gender == 2 ? [ Color(0xFFFDA4B0), Color(0xFFFBC8CC), diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index 310e2c35..f122381a 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -178,7 +178,10 @@ class _PackagesCartPageState extends State ), Padding( padding: const EdgeInsets.only(left: 12.0, right: 12.0), - child: getPaymentMethods(), + // child: getPaymentMethods(), + child: _paymentOptions(context, (paymentMethod) { + setState(() => _selectedPaymentMethod = paymentMethod); + }), ), Container( height: 0.25, diff --git a/lib/widgets/data_display/medical/LabResult/LabResultWidget.dart b/lib/widgets/data_display/medical/LabResult/LabResultWidget.dart index 4c7656f6..f4081c21 100644 --- a/lib/widgets/data_display/medical/LabResult/LabResultWidget.dart +++ b/lib/widgets/data_display/medical/LabResult/LabResultWidget.dart @@ -1,4 +1,3 @@ -import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/core/model/labs/lab_result.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart'; @@ -7,6 +6,7 @@ import 'package:diplomaticquarterapp/pages/medical/labs/passport_update_page.dar import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; @@ -14,9 +14,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import '../../text.dart'; import 'FlowChartPage.dart'; class LabResultWidget extends StatelessWidget { @@ -81,6 +79,14 @@ class LabResultWidget extends StatelessWidget { ), ) : Container(), + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Divider( + height: 1, + color: Color(0xff2E303A), + thickness: 1, + ), + ), ], ), ); @@ -152,10 +158,10 @@ class LabResultWidget extends StatelessWidget { tableRow.add( TableRow( children: [ - Utils.tableColumnTitle(TranslationBase.of(context).description), - Utils.tableColumnTitle(TranslationBase.of(context).value), - Utils.tableColumnTitle(TranslationBase.of(context).range), - Utils.tableColumnTitle(""), + Utils.tableColumnTitle(TranslationBase.of(context).description, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).value, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).range, showDivider: false), + Utils.tableColumnTitle("", showDivider: false), ], ), ); From 5474ecf2cc7b72dc9440467c40550d3dca6888e0 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 13:44:46 +0300 Subject: [PATCH 36/60] Translation update --- lib/config/localized_values.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7f77d115..4e085e46 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -421,7 +421,7 @@ const Map localizedValues = { "country": {"en": "Country", "ar": "دولة"}, "Ok": {"en": "Ok", "ar": "موافق"}, "averageWaitingTime": {"en": "Average Waiting Time:", "ar": "متوسط ​​وقت الانتظار:"}, - "waitingTime": {"en": "Waiting Time:", "ar": "وقت الانتظار:"}, + "waitingTime": {"en": "Expected waiting time:", "ar": "وقت الانتظار المتوقع:"}, "WaterConsumedInWeek": {"en": "Water consumed in a week", "ar": "معدل شرب الماء خلال الاسبوع"}, "WaterConsumedInMonth": {"en": "Water consumed in a month", "ar": "معدل شرب الماء خلال الشهر"}, "TheVerificationCodeExpiresIn": {"en": "The Verification Code Expires in", "ar": "تنتهي صلاحية رمز التحقق في"}, From c242910aa2b82db925985070c4af0aea7ca28cd9 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Wed, 27 Oct 2021 14:38:33 +0300 Subject: [PATCH 37/60] fixed issues --- lib/pages/offers_categorise_page.dart | 31 ++++++++++++++++--- .../pharmacies/screens/cart-order-page.dart | 2 +- .../screens/cart-order-preview.dart | 0 .../screens/pharmacy_module_page.dart | 3 +- .../widgets/home/PrescriptionsWidget.dart | 11 +++++-- 5 files changed, 39 insertions(+), 8 deletions(-) delete mode 100644 lib/pages/pharmacies/screens/cart-order-preview.dart diff --git a/lib/pages/offers_categorise_page.dart b/lib/pages/offers_categorise_page.dart index a95cd263..24ff4355 100644 --- a/lib/pages/offers_categorise_page.dart +++ b/lib/pages/offers_categorise_page.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/viewModels/offers_Categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; @@ -698,9 +699,31 @@ class _OffersCategorisePageState extends State { ), ) : Center( - child: Texts( - "SORRY , there's no listed offers now :(", - color: Colors.green, - )))); + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Image.asset( + 'assets/images/new-design/empty_box.png', + width: 100, + height: 100, + fit: BoxFit.cover, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(TranslationBase.of(context).noData, +// 'There is no data', + style: TextStyle(fontSize: 30), + ), + ) + ], + ), +// child: Texts( +// "SORRY , there's no listed offers now :(", +// color: Colors.green, +// ) + ))); } } diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index f81b3ef0..30509900 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -421,7 +421,7 @@ class _OrderBottomWidgetState extends State { fontSize: 14), ), color: Color(0xFF4CAF50), - disabledColor:Color(0xFF4CAF50), + disabledColor:Colors.grey[700], // disabledColor: Color(0xff005aff), ) // RaisedButton( diff --git a/lib/pages/pharmacies/screens/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-order-preview.dart deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/pages/pharmacies/screens/pharmacy_module_page.dart b/lib/pages/pharmacies/screens/pharmacy_module_page.dart index 454b391c..fad16863 100644 --- a/lib/pages/pharmacies/screens/pharmacy_module_page.dart +++ b/lib/pages/pharmacies/screens/pharmacy_module_page.dart @@ -55,9 +55,10 @@ class _PharmacyPageState extends State { BannerPager(model), GridViewButtons(model), PrescriptionsWidget(), - ShopByBrandWidget(), +// ShopByBrandWidget(), RecentlyViewedWidget(), BestSellerWidget(), + ShopByBrandWidget(), ], ), ), diff --git a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart index a2bc77e1..04449cfd 100644 --- a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart +++ b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart @@ -1,5 +1,7 @@ +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PrescriptionViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart'; @@ -11,6 +13,10 @@ import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; class PrescriptionsWidget extends StatelessWidget { + + AuthenticatedUserObject authenticatedUserObject = + locator(); + @override Widget build(BuildContext context) { return BaseView( @@ -20,7 +26,7 @@ class PrescriptionsWidget extends StatelessWidget { } }, allowAny: true, - builder: (_, model, wi) => model.prescriptionsList.length > 0 + builder: (_, model, wi) => model.prescriptionsList.length > 0 && authenticatedUserObject.isLogin ? NetworkBaseView( isLocalLoader: true, baseViewModel: model, @@ -179,7 +185,8 @@ class PrescriptionsWidget extends StatelessWidget { ), ), ) - : Container(), + : Container( + ), ); } } From 2c30b5a494e622cca2fd2200df4347d604058563 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Wed, 27 Oct 2021 15:18:32 +0300 Subject: [PATCH 38/60] fix issues --- lib/core/service/client/base_app_client.dart | 1 + .../pharmacyModule/PharmacyAddressesViewModel.dart | 6 ++++++ lib/pages/final_products_page.dart | 2 +- lib/pages/landing/landing_page_pharmcy.dart | 2 +- lib/pages/parent_categorise_page.dart | 2 +- .../pharmacies/screens/{ => cart-page}/cart-order-page.dart | 2 +- .../screens/product-details/footor/footer-widget.dart | 2 +- .../pharmacies/screens/product-details/product-detail.dart | 2 +- .../product-details/shared/product_details_app_bar.dart | 2 +- lib/pages/sub_categorise_page.dart | 2 +- lib/widgets/pharmacy/product_tile.dart | 2 +- 11 files changed, 16 insertions(+), 9 deletions(-) rename lib/pages/pharmacies/screens/{ => cart-page}/cart-order-page.dart (99%) diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 5abbe81e..108b9695 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -433,6 +433,7 @@ class BaseAppClient { } print("URL : $url"); + var ss = json.encode(queryParams); if (await Utils.checkConnection()) { final response = await http.get(url.trim(), headers: { diff --git a/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart b/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart index 2f2d1467..b6420c9c 100644 --- a/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart @@ -4,6 +4,8 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Country.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/pharmacyAddress_service.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:flutter_webrtc/flutter_webrtc.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import '../../../locator.dart'; @@ -75,13 +77,17 @@ class PharmacyAddressesViewModel extends BaseViewModel { sendingAddress.createdOnUtc = DateTime.now().toString(); if (editedAddress == null) { + + ///TODO Fatima* await _pharmacyAddressService.addCustomerAddress(sendingAddress); + } else { await _pharmacyAddressService.editCustomerAddress(sendingAddress); } if (_pharmacyAddressService.hasError) { error = _pharmacyAddressService.error; + Utils.showErrorToast(error); setState(ViewState.Error); } else { setState(ViewState.Idle); diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 854b66a6..9c3a9e43 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; diff --git a/lib/pages/landing/landing_page_pharmcy.dart b/lib/pages/landing/landing_page_pharmcy.dart index aa6f0d1c..2e251f3b 100644 --- a/lib/pages/landing/landing_page_pharmcy.dart +++ b/lib/pages/landing/landing_page_pharmcy.dart @@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/profile/profile.dart'; diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index 18133bb2..c40fa6bd 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -6,7 +6,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_deta import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/sub_categorise_page.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart similarity index 99% rename from lib/pages/pharmacies/screens/cart-order-page.dart rename to lib/pages/pharmacies/screens/cart-page/cart-order-page.dart index 30509900..a15c5c50 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart @@ -19,7 +19,7 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:provider/provider.dart'; -import 'cart-page/cart-order-preview.dart'; +import 'cart-order-preview.dart'; class CartOrderPage extends StatefulWidget { diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart index ca8222ac..69f16ac2 100644 --- a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -1,7 +1,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; diff --git a/lib/pages/pharmacies/screens/product-details/product-detail.dart b/lib/pages/pharmacies/screens/product-details/product-detail.dart index 4cee4ba3..cb38ca4f 100644 --- a/lib/pages/pharmacies/screens/product-details/product-detail.dart +++ b/lib/pages/pharmacies/screens/product-details/product-detail.dart @@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/recommended_products.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart'; diff --git a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart index a9e2a66c..5febe30c 100644 --- a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -2,7 +2,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index 6c41f550..90806a82 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; diff --git a/lib/widgets/pharmacy/product_tile.dart b/lib/widgets/pharmacy/product_tile.dart index 1c2f87cc..af1e75ec 100644 --- a/lib/widgets/pharmacy/product_tile.dart +++ b/lib/widgets/pharmacy/product_tile.dart @@ -1,6 +1,6 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/ProductReview.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; From c1ce3a0489cb67194f011297362e176b5c050051 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 27 Oct 2021 15:44:49 +0300 Subject: [PATCH 39/60] blood sugar dialog improvement. --- lib/pages/Blood/blood_donation.dart | 23 +- .../blood_suger/AddBloodSugarPage.dart | 417 +++++++++--------- 2 files changed, 219 insertions(+), 221 deletions(-) diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index be58b644..8fb12f33 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -227,17 +227,18 @@ class _BloodDonationPageState extends State { child: InkWell( onTap: () { showDialog( - context: context, - builder: (_) => AssetGiffyDialog( - title: Text( - "", - style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600), - ), - image: Image.asset('assets/images/BloodChrt_EN.png'), - buttonCancelText: Text(TranslationBase.of(context).cancel), - buttonCancelColor: Colors.grey, - onlyCancelButton: true, - )); + context: context, + builder: (_) => AssetGiffyDialog( + title: Text( + "", + style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600), + ), + image: Image.asset('assets/images/BloodChrt_EN.png'), + buttonCancelText: Text(TranslationBase.of(context).cancel), + buttonCancelColor: Colors.grey, + onlyCancelButton: true, + ), + ); }, child: Container(width: 250, height: 200, child: Image.asset('assets/images/BloodChrt_EN.png'), color: Colors.white), ), diff --git a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart index 82375322..8e47e4e8 100644 --- a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart @@ -8,8 +8,8 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -41,6 +41,8 @@ class _AddBloodSugarPageState extends State { String measureUnitSelectedType = 'mg/dlt'; int measuredTime = 1; bool isButtonDisabled = true; + + int _selectedMeasureUnitIndex = 0; final List measureUnitList = ['mg/dlt', 'mol/L']; final List measureTimeEnList = [ 'Before Breakfast', @@ -66,6 +68,7 @@ class _AddBloodSugarPageState extends State { "صائم", "آخر", ]; + int _selectedMeasureTimeIndex; String measureTimeSelectedType; @override @@ -88,212 +91,198 @@ class _AddBloodSugarPageState extends State { Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - isShowAppBar: true, - showNewAppBar: true, - showNewAppBarTitle: true, - appBarTitle: widget.isUpdate ? TranslationBase.of(context).update : TranslationBase.of(context).add, - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: TranslationBase.of(context).sugarAdd, - controller: _bloodSugarValueController, - keyboardType: TextInputType.number, - onChanged: (value) => validateForm(), - fontWeight: FontWeight.normal, - fontSize: 14, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureUnitDialog(); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureUnitSelectedType), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: widget.isUpdate ? TranslationBase.of(context).update : TranslationBase.of(context).add, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Column( + children: [ + NewTextFields( + hintText: TranslationBase.of(context).sugarAdd, + controller: _bloodSugarValueController, + keyboardType: TextInputType.number, + onChanged: (value) => validateForm(), + fontWeight: FontWeight.normal, + fontSize: 14, + ), + SizedBox(height: 12), + InkWell( + onTap: () { + confirmSelectMeasureUnitDialog(); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureUnitSelectedType), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], + ), ), ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker(context, showTitleActions: true, minTime: DateTime(DateTime.now().year - 1, 1, 1), maxTime: DateTime.now(), onConfirm: (date) { - setState(() { - bloodSugarDate = date; - }); - }, currentTime: bloodSugarDate, locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(TranslationBase.of(context).date), - Texts(getDate()), - ], + SizedBox(height: 12), + InkWell( + onTap: () { + DatePicker.showDatePicker(context, showTitleActions: true, minTime: DateTime(DateTime.now().year - 1, 1, 1), maxTime: DateTime.now(), onConfirm: (date) { + setState(() { + bloodSugarDate = date; + }); + }, currentTime: bloodSugarDate, locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).date), + Texts(getDate()), + ], + ), ), ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showTimePicker(context, showTitleActions: true, onConfirm: (date) { - setState(() { - timeSugarDate = date; - }); - }, currentTime: timeSugarDate, locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts(TranslationBase.of(context).time), Texts(getTime())], + SizedBox(height: 12), + InkWell( + onTap: () { + DatePicker.showTimePicker(context, showTitleActions: true, onConfirm: (date) { + setState(() { + timeSugarDate = date; + }); + }, currentTime: timeSugarDate, locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [Texts(TranslationBase.of(context).time), Texts(getTime())], + ), ), ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic ? measureTimeArList : measureTimeEnList); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureTimeSelectedType ?? TranslationBase.of(context).other), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], + SizedBox(height: 12), + InkWell( + onTap: () { + confirmSelectMeasureTimeDialog(projectViewModel.isArabic ? measureTimeArList : measureTimeEnList); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureTimeSelectedType ?? TranslationBase.of(context).other), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], + ), ), ), - ), - widget.isUpdate - ? Container( - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - InkWell( - child: Texts( - TranslationBase.of(context).delete, - decoration: TextDecoration.underline, - fontWeight: FontWeight.bold, - color: Colors.red[900], - ), - onTap: () { - ConfirmDialog dialog = new ConfirmDialog( + widget.isUpdate + ? Container( + padding: EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + child: Texts( + TranslationBase.of(context).delete, + decoration: TextDecoration.underline, + fontWeight: FontWeight.bold, + color: Colors.red[900], + ), + onTap: () { + showDialog( context: context, - confirmMessage: TranslationBase.of(context).removeMeasure, - okText: TranslationBase.of(context).ok, - cancelText: TranslationBase.of(context).cancel, - okFunction: () async { - ConfirmDialog.closeAlertDialog(context); - - GifLoaderDialogUtils.showMyDialog(context); - widget.bloodSugarViewMode.deactivateDiabeticStatus(lineItemNo: widget.lineItemNo).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) + child: ConfirmWithMessageDialog( + message: TranslationBase.of(context).removeMeasure, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + widget.bloodSugarViewMode.deactivateDiabeticStatus(lineItemNo: widget.lineItemNo).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) + AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); - else - Navigator.pop(context); - }).catchError((e) { - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); - }); - }, - cancelFunction: () => {}); - dialog.showAlertDialog(context); - }, - ) - ], - )) - : Container() - ], + }); + }, + ), + ); + }, + ) + ], + ), + ) + : Container() + ], + ), ), ), - ), - bottomSheet: Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: Padding( - padding: const EdgeInsets.all(20.0), - child: DefaultButton( - TranslationBase.of(context).save.toUpperCase(), - isButtonDisabled - ? null - : () async { - if (_bloodSugarValueController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - if (widget.isUpdate) { - await widget.bloodSugarViewMode.updateDiabtecResult( - month: bloodSugarDate, - hour: timeSugarDate, - diabtecUnit: measureUnitSelectedType, - measuredTime: measuredTime, - lineItemNo: widget.lineItemNo, - bloodSugerResult: _bloodSugarValueController.text.toString()); - - GifLoaderDialogUtils.hideDialog(context); - if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) - AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); - else - Navigator.pop(context); - } else { - await widget.bloodSugarViewMode.addDiabtecResult( + DefaultButton( + TranslationBase.of(context).save, + isButtonDisabled + ? null + : () async { + if (_bloodSugarValueController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + if (widget.isUpdate) { + await widget.bloodSugarViewMode.updateDiabtecResult( + month: bloodSugarDate, + hour: timeSugarDate, diabtecUnit: measureUnitSelectedType, measuredTime: measuredTime, - bloodSugerResult: _bloodSugarValueController.text.toString(), - bloodSugerDateChart: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - ); + lineItemNo: widget.lineItemNo, + bloodSugerResult: _bloodSugarValueController.text.toString()); - GifLoaderDialogUtils.hideDialog(context); - if (widget.bloodSugarViewMode.state == ViewState.Error) - AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); - else - Navigator.pop(context); - } + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) + AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + } else { + await widget.bloodSugarViewMode.addDiabtecResult( + diabtecUnit: measureUnitSelectedType, + measuredTime: measuredTime, + bloodSugerResult: _bloodSugarValueController.text.toString(), + bloodSugerDateChart: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + ); + + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.Error) + AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); } - }, - disabledColor: Colors.grey, - ), - ), - )); + } + }, + disabledColor: Colors.grey, + ).insideContainer, + ], + ), + ); } String getDate() { @@ -305,33 +294,41 @@ class _AddBloodSugarPageState extends State { } void confirmSelectMeasureUnitDialog() { + List list = [ + RadioSelectionDialogModel("mg/dlt", 0), + RadioSelectionDialogModel("mol/L", 1), + ]; + showDialog( context: context, - child: RadioStringDialog( - radioList: measureUnitList, - title: TranslationBase.of(context).measureUnit, - selectedValue: measureUnitSelectedType, - onValueSelected: (value) { - setState(() { - measureUnitSelectedType = value; - }); + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedMeasureUnitIndex, + onValueSelected: (index) { + _selectedMeasureUnitIndex = index; + measureUnitSelectedType = list[index].title; + setState(() {}); }, ), ); } - void confirmSelectMeasureTimeDialog(List list) { + void confirmSelectMeasureTimeDialog(List dataList) { + List list = [ + for (int i = 0; i < dataList.length; i++) RadioSelectionDialogModel(dataList[i], i), + ]; + showDialog( context: context, - child: RadioStringDialog( - radioList: list, - title: TranslationBase.of(context).measureTime, - selectedValue: measureTimeSelectedType, - onValueSelected: (value) { - setState(() { - measureTimeSelectedType = value; - measuredTime = list.indexOf(value); - }); + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedMeasureTimeIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedMeasureTimeIndex = index; + measureTimeSelectedType = list[index].title; + measuredTime = index; + setState(() {}); }, ), ); From 9fd2304d3344f45d129ec232d1b5f713551cd74a Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 27 Oct 2021 16:31:24 +0300 Subject: [PATCH 40/60] tamara. --- android/gradle.properties | 2 +- assets/images/svg/tamara.svg | 4 + lib/config/config.dart | 1 + .../responses/tamara_payment_option.dart | 35 +++++ .../PackagesOffersServices.dart | 28 +++- .../OfferAndPackagesCartPage.dart | 30 ++++- lib/widgets/others/app_scaffold_widget.dart | 2 +- lib/widgets/single_selection_dialog.dart | 127 ++++++++++++++++++ 8 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 assets/images/svg/tamara.svg create mode 100644 lib/core/model/packages_offers/responses/tamara_payment_option.dart create mode 100644 lib/widgets/single_selection_dialog.dart diff --git a/android/gradle.properties b/android/gradle.properties index 38c8d454..a5965ab8 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true android.useAndroidX=true -android.enableJetifier=true +android.enableJetifier=true \ No newline at end of file diff --git a/assets/images/svg/tamara.svg b/assets/images/svg/tamara.svg new file mode 100644 index 00000000..acc21074 --- /dev/null +++ b/assets/images/svg/tamara.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index bbbacaa4..27d60972 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,6 +14,7 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; +const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; const BASE_URL = 'https://uat.hmgwebservices.com/'; // const BASE_URL = 'https://hmgwebservices.com/'; diff --git a/lib/core/model/packages_offers/responses/tamara_payment_option.dart b/lib/core/model/packages_offers/responses/tamara_payment_option.dart new file mode 100644 index 00000000..ad79f5f3 --- /dev/null +++ b/lib/core/model/packages_offers/responses/tamara_payment_option.dart @@ -0,0 +1,35 @@ +class TamaraPaymentOption { + String name; + double minLimit; + double maxLimit; + int id; + + String fullName() => '$name Months'; + + TamaraPaymentOption({ + this.name, + this.minLimit, + this.maxLimit, + this.id}); + + + @override + String toString() => fullName(); + + TamaraPaymentOption.fromJson(dynamic json) { + name = json["name"]; + minLimit = json["min_limit"]; + maxLimit = json["max_limit"]; + id = json["id"]; + } + + Map toJson() { + var map = {}; + map["name"] = name; + map["min_limit"] = minLimit; + map["max_limit"] = maxLimit; + map["id"] = id; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 46e042a4..17abdc05 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -26,6 +27,7 @@ class OffersAndPackagesServices extends BaseService { List categoryList = List(); List productList = List(); List latestOffersList = List(); + List tamaraPaymentOptions = List(); List bestSellerList = List(); List bannersList = List(); List cartItemList = List(); @@ -71,6 +73,25 @@ class OffersAndPackagesServices extends BaseService { return productList; } + Future> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async { + if(tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) + return tamaraPaymentOptions; + + var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['payment_option'].forEach((json) { + tamaraPaymentOptions.add(TamaraPaymentOption.fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }); + + return tamaraPaymentOptions; + } + Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; @@ -313,20 +334,19 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Place Order // -------------------- - Future placeOrder({@required String paymentOption, @required BuildContext context, bool showLoading = true}) async{ + Future placeOrder({@required Map paymentParams, @required BuildContext context, bool showLoading = true}) async{ Future errorThrow; - var jsonBody = { + var jsonBody = { "order": { "customer_id" : customer.id, "billing_address": { "email": patientUser.emailAddress, "phone_number": patientUser.mobileNumber }, - "payment_method_system_name": "Payments.PayFort", - "payment_option": paymentOption } }; + jsonBody.addAll(paymentParams); int order_id; _showLoading(context, showLoading); diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index 5ef0a968..53b4895c 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -2,6 +2,7 @@ import 'package:after_layout/after_layout.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; @@ -12,6 +13,7 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/single_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -70,7 +72,7 @@ class _PackagesCartPageState extends State await viewModel.service .placeOrder( context: context, - paymentOption: _selectedPaymentMethod.toUpperCase()) + paymentParams: _selectedPaymentParams) .then((orderId) { if (orderId.runtimeType == int) { // result == order_id @@ -177,7 +179,7 @@ class _PackagesCartPageState extends State ), _paymentOptions(context, (paymentMethod) { setState(() => _selectedPaymentMethod = paymentMethod); - }), + }, viewModel: viewModel), Container( height: 0.25, color: Colors.grey[300], @@ -229,7 +231,8 @@ class _PackagesCartPageState extends State // /* Payment Footer Widgets */ // --------------------------- String _selectedPaymentMethod; -Widget _paymentOptions(BuildContext context, Function(String) onSelected) { +Map _selectedPaymentParams; +Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) { double height = 30; Widget buttonContent(bool isSelected, String imageName) { @@ -252,6 +255,12 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: Image.asset('assets/images/new-design/$imageName'), )); } + + Future selectTamaraPaymentOption() async{ + final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true); + final selected = await SingleSelectionDialog(tamara_options, title: 'Select the tamara installment plan').show(context); + return selected.name; + } return Padding( padding: const EdgeInsets.all(5), @@ -261,9 +270,18 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ + InkWell( + child: buttonContent(_selectedPaymentMethod == "tamara", 'mada.png'), + onTap: () async{ + final tamara_option = await selectTamaraPaymentOption(); + _selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option}; + onSelected("tamara"); + }, + ), InkWell( child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MADA"}; onSelected("mada"); }, ), @@ -273,6 +291,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { InkWell( child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "VISA"}; onSelected("visa"); }, ), @@ -280,9 +299,9 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { width: 5, ), InkWell( - child: buttonContent( - _selectedPaymentMethod == "mastercard", 'mastercard.png'), + child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MASTERCARD"}; onSelected("mastercard"); }, ), @@ -293,6 +312,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: buttonContent( _selectedPaymentMethod == "installment", 'installment.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"}; onSelected("installment"); }, ), diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 8729fe4a..11879f20 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -357,7 +357,7 @@ class AppBarWidgetState extends State { icon: Badge( position: BadgePosition.topStart(top: -15, start: -10), badgeContent: Text( - orderPreviewViewModel.cartResponse.quantityCount.toString() /*_badgeText*/, + _badgeText, style: TextStyle(fontSize: 9, color: Colors.white, fontWeight: FontWeight.normal), ), child: Icon(Icons.shopping_cart)), diff --git a/lib/widgets/single_selection_dialog.dart b/lib/widgets/single_selection_dialog.dart new file mode 100644 index 00000000..b8466b65 --- /dev/null +++ b/lib/widgets/single_selection_dialog.dart @@ -0,0 +1,127 @@ +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:manage_calendar_events/manage_calendar_events.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +class SingleSelectionDialog extends StatefulWidget { + final List items; + final String title; + + SingleSelectionDialog(this.items, {Widget icon, @required this.title}); + + Future show(BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)), + insetPadding: EdgeInsets.all(21), + child: this, + ); + }, + ); + } + + @override + _SingleSelectionDialogState createState() => _SingleSelectionDialogState(); +} + +class _SingleSelectionDialogState extends State { + int i = 0; + + @override + Widget build(BuildContext context) { + return Container( + //width: MediaQuery.of(context).size.width / 0.8, + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.notifications_active, + color: Color(0xff2B353E), + size: 50, + ), + IconButton( + icon: Icon(Icons.clear), + color: Color(0xff2B353E), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + mHeight(20), + Text( + widget.title, + style: TextStyle( + fontSize: 16, + color: Color(0xff2B353E), + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: optionList(widget.items), + ), + + mHeight(12), + DefaultButton( + TranslationBase.of(context).done, + () { + Navigator.pop(context, widget.items[i]); + }, + color: CustomColors.green, + ), + ], + ), + ); + } + + Widget optionList(List options){ + return ListView( + shrinkWrap: true, + children: List.generate(options.length, (index){ + + final opt = options[index]; + return Row( + children: [ + Radio( + value: index, + groupValue: i, + onChanged: (int value) { + setState(() { + i = value; + }); + }, + ), + Text( + opt.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ); + }), + ); + } +} From b08dfb117cdb45857fd87527d52b01f22da101d4 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 16:36:14 +0300 Subject: [PATCH 41/60] Updates & fixes --- assets/images/pharmacy/offers_banner.png | Bin 0 -> 60027 bytes assets/images/pharmacy/offers_banner_ar.png | Bin 0 -> 57673 bytes .../images/pharmacy_module/offers_banner.png | Bin 0 -> 60027 bytes .../pharmacy_module/offers_banner_ar.png | Bin 0 -> 57673 bytes lib/config/config.dart | 9 +- lib/config/localized_values.dart | 2 +- .../service/PrescriptionDeliveryService.dart | 33 +- .../PrescriptionDeliveryViewModel.dart | 36 +- .../medical/prescriptions_view_model.dart | 1 - .../pharmacy_module_view_model.dart | 28 +- .../PrescriptionOrderOverveiw.dart | 2 +- .../heartrate/heartrateTracker.dart | 12 +- .../smart_watch_instructions.dart | 1007 ++++++++--------- .../screens/pharmacy_module_page.dart | 2 - .../pharmacies/widgets/home/BannerPager.dart | 64 +- .../widgets/home/GridViewButtons.dart | 76 +- 16 files changed, 596 insertions(+), 676 deletions(-) create mode 100644 assets/images/pharmacy/offers_banner.png create mode 100644 assets/images/pharmacy/offers_banner_ar.png create mode 100644 assets/images/pharmacy_module/offers_banner.png create mode 100644 assets/images/pharmacy_module/offers_banner_ar.png diff --git a/assets/images/pharmacy/offers_banner.png b/assets/images/pharmacy/offers_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..6eab63fb59432fe9b38fb8af682ec42378512fe1 GIT binary patch literal 60027 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�J`G(IGKv`FITcy3{kA=lZYs#%6+W+Cn=Wu@ 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 N6$MTCDp~8u{{w*XM}7bR literal 0 HcmV?d00001 diff --git a/assets/images/pharmacy/offers_banner_ar.png b/assets/images/pharmacy/offers_banner_ar.png new file mode 100644 index 0000000000000000000000000000000000000000..d987d3c630da14832433e118426dff2b1a06b4c6 GIT binary patch literal 57673 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 Welb$px*zC%1C$`@;Br}u&;JL~@vCtF literal 0 HcmV?d00001 diff --git a/assets/images/pharmacy_module/offers_banner.png b/assets/images/pharmacy_module/offers_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..6eab63fb59432fe9b38fb8af682ec42378512fe1 GIT binary patch literal 60027 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�J`G(IGKv`FITcy3{kA=lZYs#%6+W+Cn=Wu@ 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 N6$MTCDp~8u{{w*XM}7bR literal 0 HcmV?d00001 diff --git a/assets/images/pharmacy_module/offers_banner_ar.png b/assets/images/pharmacy_module/offers_banner_ar.png new file mode 100644 index 0000000000000000000000000000000000000000..d987d3c630da14832433e118426dff2b1a06b4c6 GIT binary patch literal 57673 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 Welb$px*zC%1C$`@;Br}u&;JL~@vCtF literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index bbbacaa4..fe92ba99 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,8 +14,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; @@ -457,6 +457,11 @@ const ADD_RRT_ORDER_RC = "rc/api/rrt/add"; const GET_ALL_RRT_ORDERS_RC = "rc/api/rrt/list"; const UPDATE_RRT_ORDER_RC = 'rc/api/rrt/update'; +// PRESCRIPTION RC SERVICES +const ADD_PRESCRIPTION_ORDER_RC = "rc/api/prescription/add"; +const GET_ALL_PRESCRIPTION_ORDERS_RC = "rc/api/prescription/list"; +const UPDATE_PRESCRIPTION_ORDER_RC = 'rc/api/prescription/update'; + //Pharmacy wishlist const GET_WISHLIST = "shopping_cart_items/"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 4e085e46..f26dccf5 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1596,7 +1596,7 @@ const Map localizedValues = { "ios-instructions-2": { "en": "Make sure that your Apple Watch is connected with the Watch & Health Apps.", "ar": "تأكد من اتصال Apple Watch بتطبيقات Watch & Health." }, "ios-instructions-3": { "en": "Make sure that data like heart rate, steps, distance etc. are being shown on your health app.", "ar": "تأكد من عرض بيانات مثل معدل ضربات القلب والخطوات والمسافة وما إلى ذلك على تطبيق صحتك." }, "supportedWatches": { "en": "Supported SmartWatches", "ar": "الساعات الذكية المدعومة" }, - "watchInstructions": { "en": "Watch Instructions:", "ar": "تعليمات الساعة:" }, + "watchInstructions": { "en": "View watch instructions", "ar": "عرض تعليمات الساعة" }, "monthlyTab": {"en": "Monthly", "ar": "شهري"}, "moreSupportedWatches": {"en": "More Supported Smartwatches...", "ar": "المزيد من الساعات الذكية المدعومة..."}, "android-instructions-1": { "en": "Make sure that you have installed 'WearOS' & 'Google Fit' apps from Google PlayStore.", "ar": "تأكد من تثبيت تطبيقات 'WearOS' و 'Google Fit' من متجر Google PlayStore." }, diff --git a/lib/core/service/PrescriptionDeliveryService.dart b/lib/core/service/PrescriptionDeliveryService.dart index c36efe89..104b390d 100644 --- a/lib/core/service/PrescriptionDeliveryService.dart +++ b/lib/core/service/PrescriptionDeliveryService.dart @@ -2,13 +2,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class PrescriptionDeliveryService extends BaseService { - Future insertDeliveryOrder( - {int lineItemNo, - double latitude, - double longitude, - int appointmentNo, - int createdBy, - int dischargeID}) async { + Future insertDeliveryOrder({int lineItemNo, double latitude, double longitude, int appointmentNo, int createdBy, int dischargeID}) async { hasError = false; Map body = Map(); body['LineItemNo'] = lineItemNo; @@ -17,11 +11,26 @@ class PrescriptionDeliveryService extends BaseService { body['AppointmentNo'] = appointmentNo; body['CreatedBy'] = createdBy; body['DischargeID'] = dischargeID; - await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { - var asd=""; - }, - onFailure: (String error, int statusCode) { + await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { + var asd = ""; + }, onFailure: (String error, int statusCode) { + hasError = true; + print(error); + super.error = error; + }, body: body); + } + + Future insertDeliveryOrderRC({double latitude, double longitude, int appointmentNo, int createdBy, int dischargeID}) async { + hasError = false; + Map body = Map(); + body['latitude'] = latitude; + body['longitude'] = longitude; + body['AppointmentNo'] = appointmentNo; + body['CreatedBy'] = createdBy; + body['DischargeID'] = dischargeID; + await baseAppClient.post(ADD_PRESCRIPTION_ORDER_RC, onSuccess: (dynamic response, int statusCode) { + var asd = ""; + }, onFailure: (String error, int statusCode) { hasError = true; print(error); super.error = error; diff --git a/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart index 424a4b20..ada4da78 100644 --- a/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart +++ b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart @@ -7,15 +7,11 @@ import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import '../../../locator.dart'; class PrescriptionDeliveryViewModel extends BaseViewModel { - CustomerAddressesService _customerAddressesService = - locator(); - PharmacyModuleService _pharmacyModuleService = - locator(); - PrescriptionDeliveryService _prescriptionDeliveryService = - locator(); + CustomerAddressesService _customerAddressesService = locator(); + PharmacyModuleService _pharmacyModuleService = locator(); + PrescriptionDeliveryService _prescriptionDeliveryService = locator(); - List get addressesList => - _customerAddressesService.addressesList; + List get addressesList => _customerAddressesService.addressesList; Future getCustomerInfo() async { setState(ViewState.Busy); @@ -27,28 +23,16 @@ class PrescriptionDeliveryViewModel extends BaseViewModel { if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); - } else { - } + } else {} await getCustomerAddresses(); } - Future insertDeliveryOrder( - {int lineItemNo, - double latitude, - double longitude, - int appointmentNo, - int createdBy, - int dischargeID}) async { - + Future insertDeliveryOrder({int lineItemNo, double latitude, double longitude, int appointmentNo, int createdBy, int dischargeID}) async { setState(ViewState.BusyLocal); - await _prescriptionDeliveryService.insertDeliveryOrder( - lineItemNo: lineItemNo, - latitude: latitude, - longitude: longitude, - appointmentNo: appointmentNo, - createdBy: createdBy, - dischargeID: dischargeID - ); + // await _prescriptionDeliveryService.insertDeliveryOrder( + // lineItemNo: lineItemNo, latitude: latitude, longitude: longitude, appointmentNo: appointmentNo, createdBy: createdBy, dischargeID: dischargeID); + await _prescriptionDeliveryService.insertDeliveryOrderRC( + latitude: latitude, longitude: longitude, appointmentNo: appointmentNo, createdBy: createdBy, dischargeID: dischargeID); if (_prescriptionDeliveryService.hasError) { error = _prescriptionDeliveryService.error; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/medical/prescriptions_view_model.dart b/lib/core/viewModels/medical/prescriptions_view_model.dart index 0c1fafdf..03018878 100644 --- a/lib/core/viewModels/medical/prescriptions_view_model.dart +++ b/lib/core/viewModels/medical/prescriptions_view_model.dart @@ -77,7 +77,6 @@ class PrescriptionsViewModel extends BaseViewModel { } getPrescriptionsOrders({bool showLoading = false}) async { - // print(showLoading); setState(ViewState.Busy); Future.delayed(new Duration(milliseconds: 300)).then((value) async { await _prescriptionsService.getPrescriptionsOrders(); diff --git a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart index facccf1e..27fe3234 100644 --- a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart @@ -1,16 +1,12 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; -import 'package:diplomaticquarterapp/core/service/medical/prescriptions_service.dart'; //import 'package:diplomaticquarterapp/core/model/prescriptions/perscription_pharmacy.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; -import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/recommendedProduct_service.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; @@ -20,13 +16,11 @@ import '../../../locator.dart'; class PharmacyModuleViewModel extends BaseViewModel { PharmacyModuleService _pharmacyService = locator(); - RecommendedProductService _recommendedProductService = - locator(); + RecommendedProductService _recommendedProductService = locator(); List get bannerList => _pharmacyService.bannerItems; - List get recommendedProductList => - _recommendedProductService.recommendedList; + List get recommendedProductList => _recommendedProductService.recommendedList; Future generatePharmacyToken() async { setState(ViewState.Busy); @@ -40,8 +34,6 @@ class PharmacyModuleViewModel extends BaseViewModel { } Future verifyCustomer() async { - // if (authenticatedUserObject.isLogin) await generatePharmacyToken(); - var data = await sharedPref.getObject(USER_PROFILE); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); @@ -70,11 +62,9 @@ class PharmacyModuleViewModel extends BaseViewModel { Future getBannerList() async { if (bannerList.isEmpty) { - GifLoaderDialogUtils.showMyDialog( - locator().navigatorKey.currentContext); + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); await _pharmacyService.getBannerListList(); - GifLoaderDialogUtils.hideDialog( - locator().navigatorKey.currentContext); + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); if (_pharmacyService.hasError) { error = _pharmacyService.error; setState(ViewState.Error); @@ -83,9 +73,15 @@ class PharmacyModuleViewModel extends BaseViewModel { } } - List getBannerImagesUrl() { + List getBannerImagesUrl(ProjectViewModel projectViewModel) { List images = List(); images.add('assets/images/pharmacy_module/pharmacy_logo_green.png'); + + if (projectViewModel.isArabic) + images.add('assets/images/pharmacy_module/offers_banner_ar.png'); + else + images.add('assets/images/pharmacy_module/offers_banner.png'); + _pharmacyService.bannerItems.forEach((element) { images.add(element.src); }); diff --git a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart index d4dd6efe..986fb848 100644 --- a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart +++ b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart @@ -171,7 +171,7 @@ class PrescriptionOrderOverview extends StatelessWidget { GifLoaderDialogUtils.showMyDialog(context); await model .insertDeliveryOrder( - lineItemNo: 0, + lineItemNo: 1, longitude: longitude, latitude: latitude, appointmentNo: prescriptions.appointmentNo, diff --git a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart index da82d540..077ed4bf 100644 --- a/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart +++ b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart @@ -107,7 +107,11 @@ class _HeartRateTrackerState extends State with SingleTickerPr child: new TabBarView( physics: NeverScrollableScrollPhysics(), children: [ - isWeeklyDataLoaded ? getWeeklyHeartRateDetails() : Container(), + isWeeklyDataLoaded + ? avgWeeklyHearRateValue != 0 + ? getWeeklyHeartRateDetails() + : getNoDataWidget(context) + : Container(), isMonthlyDataLoaded ? getMonthlyHeartRateDetails() : Container(), isYearlyDataLoaded ? getYearlyHeartRateDetails() : Container() ], @@ -135,9 +139,11 @@ class _HeartRateTrackerState extends State with SingleTickerPr weeklyDataLength++; } }); - generateWeekData(); + if (weekyHearRateList.isNotEmpty) generateWeekData(); setState(() { - weeklyStatsAvgValue = avgWeeklyHearRateValue ~/ weeklyDataLength; + if (avgWeeklyHearRateValue != 0) { + weeklyStatsAvgValue = avgWeeklyHearRateValue ~/ weeklyDataLength; + } isWeeklyDataLoaded = true; }); }).catchError((err) { diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index 4fc233db..17d9d8a8 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -9,7 +9,6 @@ import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchI import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -40,19 +39,31 @@ class _SmartWatchInstructionsState extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).smartWatches, - isShowAppBar: true, - isShowDecPage: true, - showNewAppBar: true, - showNewAppBarTitle: true, - description: TranslationBase.of(context).infoHealthData, - imagesInfo: [ - ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/0.png'), - ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/1.png') - ], - body: Container( - child: Platform.isIOS ? _getAppleWatchInstructions() : _getGoogleWatchInstructions(), - )); + appBarTitle: TranslationBase.of(context).smartWatches, + isShowAppBar: true, + isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, + description: TranslationBase.of(context).infoHealthData, + imagesInfo: [ + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/0.png'), + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/health-data/ar/1.png') + ], + body: Container( + child: Platform.isIOS ? _getAppleWatchInstructions() : _getGoogleWatchInstructions(), + ), + bottomSheet: Container( + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 30.0), + child: DefaultButton( + TranslationBase.of(context).continues, + () { + _openHealthDataList(); + }, + color: Color(0xff359846), + ), + ), + ); } _getAppleWatchInstructions() { @@ -61,250 +72,200 @@ class _SmartWatchInstructionsState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Flexible( - child: CarouselSlider( - carouselController: buttonCarouselController, - options: CarouselOptions(enableInfiniteScroll: false, viewportFraction: 0.95, height: MediaQuery.of(context).size.height * 0.9), - items: [1, 2].map((i) { - return Builder( - builder: (BuildContext context) { - return Container( - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.symmetric(horizontal: 5.0), - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white.withOpacity(1.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + Container( + width: double.infinity, + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600)), + ), + Container( + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/apple-watch-1.jpeg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 1", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], ), - child: i == 1 - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), - ), - Container( - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/apple-watch-1.jpeg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 1", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/apple-watch-2.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/apple-watch-3.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/apple-watch-4.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/apple-watch-5.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 5", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/Apple-Watch-6.png", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Apple Watch Series 6", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.fromLTRB(15.0, 40.0, 15.0, 0.0), - child: DefaultButton( - TranslationBase.of(context).continues, - () { - buttonCarouselController.nextPage(); - }, - color: Color(0xff359846), - ), - ), - ], - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).watchInstructions, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).iosInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).iosInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Text(TranslationBase.of(context).iosInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), - ), - Padding( - padding: const EdgeInsets.fromLTRB(12.0, 50.0, 12.0, 20.0), - child: Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).syncHealthData, - () {}, - color: Color(0xFFD02127), - disabledColor: Color(0xff28323A).withOpacity(0.3), - ), - ), - mWidth(12), - if (hasAlreadySynced) - Expanded( - child: DefaultButton( - TranslationBase.of(context).alreadySynced, - () { - _openHealthDataList(); - }, - color: Color(0xff359846), - ), - ), - ], - ), - ), - ], + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/apple-watch-2.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/apple-watch-3.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/apple-watch-4.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/apple-watch-5.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 5", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/Apple-Watch-6.png", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Apple Watch Series 6", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), ), - )); + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + ), + Container( + margin: EdgeInsets.all(10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + ), + InkWell( + onTap: () { + showInstructionsDialog(); }, - ); - }).toList(), + child: Padding( + padding: const EdgeInsets.only(left: 10.0, right: 10.0), + child: Text(TranslationBase.of(context).watchInstructions, + style: TextStyle(color: CustomColors.accentColor, fontWeight: FontWeight.w600, letterSpacing: -0.64, decoration: TextDecoration.underline)), + ), + ), + ], ), - ) + ), ], ), ); @@ -312,204 +273,245 @@ class _SmartWatchInstructionsState extends State { _getGoogleWatchInstructions() { return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: CarouselSlider( - carouselController: buttonCarouselController, - options: CarouselOptions( - // enableInfiniteScroll: true, - viewportFraction: 0.99, - height: MediaQuery.of(context).size.height * 0.9), - items: [1, 2].map((i) { - return Builder( - builder: (BuildContext context) { - return Container( - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.symmetric(horizontal: 5.0), - child: Card( - margin: EdgeInsets.only(top: 16.0, bottom: 8.0), - // fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white.withOpacity(1.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + child: Container( + width: double.infinity, + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600)), + ), + Container( + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/huawei-watch-2.png", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Huawei Watch 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mobovi TicWatch E2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/huawei-watch-2-classic.png", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Huawei Watch", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Fossil Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/misfit-vapor-2.jpg", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("MisFit Vapor 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/lg-watch-sport.jpg", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("LG Watch Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 15.0), + child: Row( + children: [ + Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), + Container( + width: MediaQuery.of(context).size.width * 0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + ], + ), + ), + InkWell( + onTap: () { + launch("https://wearos.google.com/#find-your-watch"); + }, + child: Container( + margin: EdgeInsets.only(top: 20.0), + child: Text(TranslationBase.of(context).moreSupportedWatches, style: TextStyle(fontSize: 14.0, color: Colors.blue, decoration: TextDecoration.underline, letterSpacing: -0.36)), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + ), + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + ), + InkWell( + onTap: () { + showInstructionsDialog(); + }, + child: Padding( + padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text(TranslationBase.of(context).watchInstructions, + style: TextStyle(color: CustomColors.accentColor, fontWeight: FontWeight.w600, letterSpacing: -0.64, decoration: TextDecoration.underline)), + ), + ), + ], + ), + ), + ); + } + + showInstructionsDialog() { + showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: Dialog( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 350.0, + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TranslationBase.of(context).smartWatches, style: TextStyle(fontSize: 22.0, color: Colors.black, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + IconButton( + icon: Icon( + Icons.close, + color: Colors.black, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), ), - child: i == 1 + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).syncInstructionsIntro3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + ), + Platform.isIOS ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).supportedWatches, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), - ), - Container( - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/huawei-watch-2.png", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Huawei Watch 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Mobovi TicWatch E2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/huawei-watch-2-classic.png", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Huawei Watch", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/ticwatche2.png", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Fossil Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/misfit-vapor-2.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("MisFit Vapor 2", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/lg-watch-sport.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("LG Watch Sport", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/miBand3.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/SmartWatches/miBand4.jpg", width: 70.0, height: 70.0), - Container( - width: MediaQuery.of(context).size.width * 0.22, - child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ), - ], - ), - ), - InkWell( - onTap: () { - launch("https://wearos.google.com/#find-your-watch"); - }, - child: Container( - margin: EdgeInsets.only(top: 20.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).moreSupportedWatches, - textAlign: TextAlign.center, style: TextStyle(fontSize: 14.0, color: Colors.blue, decoration: TextDecoration.underline, letterSpacing: -0.36)), - ), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).iosInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).iosInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(15.0), - child: DefaultButton( - TranslationBase.of(context).continues, - () { - buttonCarouselController.nextPage(); - }, - color: CustomColors.green, - ), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 21.0), + child: Text(TranslationBase.of(context).iosInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), ], ) @@ -517,114 +519,37 @@ class _SmartWatchInstructionsState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).watchInstructions, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).androidInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).syncInstructionsIntro3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).androidInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).androidInstructions1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).androidInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).androidInstructions2, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), + margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 10.0), + child: Text(TranslationBase.of(context).androidInstructions4, style: TextStyle(fontSize: 14.0, letterSpacing: -0.36)), ), - Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).androidInstructions3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).androidInstructions4, style: TextStyle(fontSize: 14.0, letterSpacing: -0.34)), - ), - Padding( - padding: const EdgeInsets.fromLTRB(12.0, 50.0, 12.0, 20.0), - child: Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).syncHealthData, - () {}, - color: Color(0xFFD02127), - disabledColor: Color(0xff28323A).withOpacity(0.3), - ), - ), - mWidth(12), - if (hasAlreadySynced) - Expanded( - child: DefaultButton( - TranslationBase.of(context).alreadySynced, - () { - _openHealthDataList(); - }, - color: Color(0xff359846), - ), - ), - ], - ), - ), - // Container( - // margin: EdgeInsets.fromLTRB(15.0, 75.0, 15.0, 15.0), - // child: ButtonTheme( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(10.0), - // ), - // minWidth: MediaQuery.of(context).size.width, - // height: 45.0, - // child: RaisedButton( - // color: new Color(0xFF60686b), - // textColor: Colors.white, - // elevation: 0, - // disabledTextColor: Colors.white, - // disabledColor: new Color(0xFFbcc2c4), - // onPressed: () { - // buttonCarouselController.nextPage(); - // }, - // child: Text("SYNC HEALTH DATA", style: TextStyle(fontSize: 18.0)), - // ), - // ), - // ), - // hasAlreadySynced - // ? Container( - // margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 15.0), - // child: ButtonTheme( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(10.0), - // ), - // minWidth: MediaQuery.of(context).size.width, - // height: 45.0, - // child: RaisedButton( - // color: new Color(0xFF60686b), - // textColor: Colors.white, - // elevation: 0, - // disabledTextColor: Colors.white, - // disabledColor: new Color(0xFFbcc2c4), - // onPressed: () { - // _openHealthDataList(); - // }, - // child: Text("ALREADY SYNCED", style: TextStyle(fontSize: 18.0)), - // ), - // ), - // ) - // : Container(), ], ), - )); - }, - ); - }).toList(), + ], + ), + ), + ], + ), + ), ), - ) - ], - ), - ); + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) {}); } getLastPatientRecord(BuildContext context) { diff --git a/lib/pages/pharmacies/screens/pharmacy_module_page.dart b/lib/pages/pharmacies/screens/pharmacy_module_page.dart index 454b391c..c805144c 100644 --- a/lib/pages/pharmacies/screens/pharmacy_module_page.dart +++ b/lib/pages/pharmacies/screens/pharmacy_module_page.dart @@ -50,10 +50,8 @@ class _PharmacyPageState extends State { width: double.infinity, child: SingleChildScrollView( child: Column( - //crossAxisAlignment: CrossAxisAlignment.start, children: [ BannerPager(model), - GridViewButtons(model), PrescriptionsWidget(), ShopByBrandWidget(), RecentlyViewedWidget(), diff --git a/lib/pages/pharmacies/widgets/home/BannerPager.dart b/lib/pages/pharmacies/widgets/home/BannerPager.dart index 6f1155dd..6302f263 100644 --- a/lib/pages/pharmacies/widgets/home/BannerPager.dart +++ b/lib/pages/pharmacies/widgets/home/BannerPager.dart @@ -1,10 +1,15 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/GridViewCard.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class BannerPager extends StatefulWidget { final PharmacyModuleViewModel _model; @@ -20,14 +25,16 @@ class _BannerPagerState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return Container( child: Column( children: [ CarouselSlider( options: CarouselOptions( - aspectRatio: 7 / 2, + aspectRatio: 5 / 2, enlargeCenterPage: true, enableInfiniteScroll: false, + viewportFraction: 1.0, initialPage: 0, autoPlay: true, autoPlayInterval: Duration(seconds: 3), @@ -39,53 +46,44 @@ class _BannerPagerState extends State { }); }, ), - items: widget._model - .getBannerImagesUrl() - .mapIndexed( - (item, index) => InkWell( - onTap: () { - Navigator.push( - context, FadePage(page: OffersCategorisePage())); - }, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 1.0), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5.0)), - child: Center( - child: index == 0 - ? Image.asset( - item, - fit: BoxFit.cover, - ) - : CachedNetworkImage( - imageUrl: item, - fit: BoxFit.fitWidth, - errorWidget: (context, url, error) => - SizedBox()), - ), + items: widget._model.getBannerImagesUrl(projectViewModel).mapIndexed( + (item, index) { + return InkWell( + onTap: () { + Navigator.push(context, FadePage(page: OffersCategorisePage())); + }, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 1.0), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5.0)), + child: Center( + child: index == 0 || index == 1 + ? Image.asset( + item, + fit: BoxFit.cover, + ) + : CachedNetworkImage(imageUrl: item, fit: BoxFit.fitWidth, errorWidget: (context, url, error) => SizedBox()), ), ), ), - ) - .toList(), + ); + }, + ).toList(), ), Padding( padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: widget._model - .getBannerImagesUrl() + .getBannerImagesUrl(projectViewModel) .mapIndexed( (item, index) => Container( width: 12.0, height: 4.0, - margin: - EdgeInsets.symmetric(vertical: 0.0, horizontal: 2.0), + margin: EdgeInsets.symmetric(vertical: 0.0, horizontal: 2.0), decoration: BoxDecoration( shape: BoxShape.rectangle, - color: _current == index - ? Color.fromRGBO(0, 250, 0, 0.9) - : Color.fromRGBO(0, 0, 0, 0.4), + color: _current == index ? Color.fromRGBO(0, 250, 0, 0.9) : Color.fromRGBO(0, 0, 0, 0.4), ), ), ) diff --git a/lib/pages/pharmacies/widgets/home/GridViewButtons.dart b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart index 1a33ce74..8a549b48 100644 --- a/lib/pages/pharmacies/widgets/home/GridViewButtons.dart +++ b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart @@ -39,44 +39,44 @@ class GridViewButtons extends StatelessWidget { Navigator.push(context, FadePage(page: OffersCategorisePage())); }), ), - DashboardItem( - imageName: 'pharmacy_module/bg_2.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard(TranslationBase.of(context).medicationRefill, - 'assets/images/pharmacy_module/medication_icon.png', () { - Navigator.push( - context, FadePage(page: HomePrescriptionsPage())); - - // model.checkUserIsActivated().then((isActivated) { - // if (isActivated) { - // Navigator.push(context, FadePage(page: LakumMainPage())); - // } else { - // Navigator.push( - // context, FadePage(page: LakumActivationVidaPage())); - // } - // }); - }), - ), - DashboardItem( - imageName: 'pharmacy_module/bg_3.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard(TranslationBase.of(context).myPrescriptions, - 'assets/images/pharmacy_module/prescription_icon.png', () { - Navigator.push( - context, FadePage(page: HomePrescriptionsPage())); - }), - ), - DashboardItem( - imageName: 'pharmacy_module/bg_4.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard( - TranslationBase.of(context).searchAndScanMedication, - 'assets/images/pharmacy_module/search_scan_icon.png', - () {Navigator.push(context, FadePage(page: SearchProductsPage()));}), - ), + // DashboardItem( + // imageName: 'pharmacy_module/bg_2.png', + // opacity: 0, + // hasColorFilter: false, + // child: GridViewCard(TranslationBase.of(context).medicationRefill, + // 'assets/images/pharmacy_module/medication_icon.png', () { + // Navigator.push( + // context, FadePage(page: HomePrescriptionsPage())); + // + // // model.checkUserIsActivated().then((isActivated) { + // // if (isActivated) { + // // Navigator.push(context, FadePage(page: LakumMainPage())); + // // } else { + // // Navigator.push( + // // context, FadePage(page: LakumActivationVidaPage())); + // // } + // // }); + // }), + // ), + // DashboardItem( + // imageName: 'pharmacy_module/bg_3.png', + // opacity: 0, + // hasColorFilter: false, + // child: GridViewCard(TranslationBase.of(context).myPrescriptions, + // 'assets/images/pharmacy_module/prescription_icon.png', () { + // Navigator.push( + // context, FadePage(page: HomePrescriptionsPage())); + // }), + // ), + // DashboardItem( + // imageName: 'pharmacy_module/bg_4.png', + // opacity: 0, + // hasColorFilter: false, + // child: GridViewCard( + // TranslationBase.of(context).searchAndScanMedication, + // 'assets/images/pharmacy_module/search_scan_icon.png', + // () {Navigator.push(context, FadePage(page: SearchProductsPage()));}), + // ), ], ), ), From fd26a59b2d6d3d4516bd95e0093728f4d533f2dd Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Wed, 27 Oct 2021 17:23:53 +0300 Subject: [PATCH 42/60] live care design 1.0 --- assets/images/new-design/ic_schedule.svg | 12 + lib/config/localized_values.dart | 2 +- .../livecare/widgets/LiveCareHistoryCard.dart | 249 +++++++++++------- lib/pages/livecare/widgets/clinic_card.dart | 135 ++++++++-- lib/pages/livecare/widgets/clinic_list.dart | 123 ++++----- lib/pages/livecare/widgets/livecare_logs.dart | 7 +- 6 files changed, 344 insertions(+), 184 deletions(-) create mode 100644 assets/images/new-design/ic_schedule.svg diff --git a/assets/images/new-design/ic_schedule.svg b/assets/images/new-design/ic_schedule.svg new file mode 100644 index 00000000..c6fe44a1 --- /dev/null +++ b/assets/images/new-design/ic_schedule.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7f77d115..e7a23f3b 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1494,7 +1494,7 @@ const Map localizedValues = { "RRTRequestSuccess": {"en": "Request has been sent successfully, you will be contacted soon.", "ar": "تم إرسال الطلب بنجاح ، وسيتم الاتصال بك باسرع وقت ممكن"}, "rateDoctorAppo": {"en": "Rate DR & Appointment", "ar": "تقييم الطبيب والموعد"}, "invoice": {"en": "Invoice", "ar": "الفاتورة"}, - "requestedDate": {"en": "Reqeusted Date", "ar": "التاريخ "}, + "requestedDate": {"en": "Req Date", "ar": "التاريخ "}, "callDuration": {"en": "Call Duration", "ar": "مدة الاتصال"}, "alreadyRated": {"en": "This appointment has been previously evaluated.", "ar": "تم تقييم هذا الموعد مسبقاً"}, "insuranceCompany": {"en": "Insurance Company", "ar": "شركة تأمين"}, diff --git a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart index d3029f86..da9ad863 100644 --- a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart +++ b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart @@ -1,24 +1,29 @@ +import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart'; import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; class LiveCareHistoryCard extends StatefulWidget { ErRequestHistoryList erRequestHistoryList; + int isFirstOrLast; - LiveCareHistoryCard({this.erRequestHistoryList}); + LiveCareHistoryCard({this.erRequestHistoryList, this.isFirstOrLast}); @override _LiveCareHistoryCardState createState() => _LiveCareHistoryCardState(); @@ -40,122 +45,178 @@ class _LiveCareHistoryCardState extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); return Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + margin: EdgeInsets.only(left: 12, right: 12, top: widget.isFirstOrLast == 0 ? 12 : 6, bottom: widget.isFirstOrLast == 1 ? 12 : 6), + decoration: BoxDecoration( + color: CustomColors.accentColor, + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - child: Container( - width: MediaQuery.of(context).size.width, - // height: MediaQuery.of(context).size.height * 0.22, - padding: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text(TranslationBase.of(context).requestedDate, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), - Container( - margin: EdgeInsets.only(top: 0.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(DateUtil.getDayMonthYearHourMinuteDateFormatted(DateUtil.convertStringToDate(widget.erRequestHistoryList.arrivalTime)), style: TextStyle(fontSize: 14.0)), - Text(TranslationBase.of(context).callDuration + "\n" + getCallTime(widget.erRequestHistoryList.callDuration), textAlign: TextAlign.center, style: TextStyle(fontSize: 14.0, color: Colors.grey[600])), - ], - ), - ), - Container( - padding: EdgeInsets.all(7.0), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.green, - ), - margin: EdgeInsets.only(top: 5.0, bottom: 5.0), - child: Text(widget.erRequestHistoryList.stringCallStatus, style: TextStyle(fontSize: 14.0, color: Colors.white)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + ), + child: Container( + margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.only( + bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + widget.erRequestHistoryList.stringCallStatus == "Completed" ? widget.erRequestHistoryList.stringCallStatus : "Pending", + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: widget.erRequestHistoryList.stringCallStatus == "Completed" ? CustomColors.green : CustomColors.orange, ), - Divider( - color: Colors.grey[500], + ), + mHeight(12), + Text( + TranslationBase.of(context).requestedDate + ": " + DateUtil.getDayMonthYearHourMinuteDateFormatted(DateUtil.convertStringToDate(widget.erRequestHistoryList.arrivalTime)), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), - Container( - margin: EdgeInsets.all(5.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: InkWell( - onTap: () { - openInvoice(); - }, - child: Container( - child: Row( - children: [ - Icon(Icons.content_paste, color: Colors.red), - Container( - margin: EdgeInsets.only(left: 10.0), - child: Text(TranslationBase.of(context).invoice, textAlign: TextAlign.center, style: TextStyle(fontSize: 12.0)), + ), + mHeight(4), + Row( + children: [ + Text( + TranslationBase.of(context).callDuration + ": ", + style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, letterSpacing: -0.4, color: CustomColors.textColor), + ), + Text( + getCallTime(widget.erRequestHistoryList.callDuration), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + ], + ),mHeight(12), + Container( + width: double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + openInvoice(); + }, + child: Container( + padding: EdgeInsets.only(left: 12, right: 12, top: 6, bottom: 6), + decoration: containerRadius(CustomColors.devider, 100), + child: Row( + children: [ + SvgPicture.asset("assets/images/new/services/invoice_list.svg",width: 18,height: 18,), + mWidth(10), + Text( + TranslationBase.of(context).invoice, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 11.0, + letterSpacing: -0.46, + fontWeight: FontWeight.w600, ), - ], - ), + ), + ], ), ), ), - Expanded( - child: InkWell( - onTap: () { - openComplaint(); - }, - child: Container( - child: Row( - children: [ - Icon(Icons.add, size: 24.0, color: Colors.red), - Container( - margin: EdgeInsets.only(left: 10.0), - child: Text(TranslationBase.of(context).complaint, textAlign: TextAlign.center, style: TextStyle(fontSize: 12.0)), + ), + mWidth(12), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + openComplaint(); + }, + child: Container( + padding: EdgeInsets.only(left: 12, right: 12, top: 7, bottom: 7), + decoration: containerRadius(CustomColors.devider, 100), + child: Row( + children: [ + SvgPicture.asset("assets/images/new/services/raise_comp.svg",width: 16,height: 16,), + mWidth(10), + Expanded( + child: AutoSizeText( + TranslationBase.of(context).complaint, + textAlign: TextAlign.center, + maxLines: 1,minFontSize: 8, + style: TextStyle( + fontSize: 11.0, + letterSpacing: -0.46, + fontWeight: FontWeight.w600, + ), ), - ], - ), + ), + ], ), ), ), - Expanded( - child: InkWell( - onTap: () { - rateLiveCareAppo(); - }, - child: Container( - child: Row( - children: [ - Icon(Icons.star, size: 24.0, color: Colors.yellow[700]), - Container( - width: MediaQuery.of(context).size.width * 0.2, - margin: EdgeInsets.only(left: 9.0), - child: Text(TranslationBase.of(context).rateDoctorAppo, overflow: TextOverflow.clip, textAlign: TextAlign.center, style: TextStyle(fontSize: 11.0)), + ), + mWidth(12), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + rateLiveCareAppo(); + }, + child: Container( + padding: EdgeInsets.only(left: 12, right: 12, top: 6, bottom: 6), + decoration: containerRadius(CustomColors.devider, 100), + child: Row( + children: [ + Icon( Icons.star,size: 18,), + mWidth(10), + Text( + TranslationBase.of(context).rate, + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 11.0, + letterSpacing: -0.46, + fontWeight: FontWeight.w600, ), - ], - ), + ), + ], ), ), ), - ], - ), + ), + ], ), - ], - ), + ), + ], ), ), ); } - rateLiveCareAppo() { - if(widget.erRequestHistoryList.isAppointmentHaveRating) { + if (widget.erRequestHistoryList.isAppointmentHaveRating) { AppToast.showErrorToast(message: TranslationBase.of(context).alreadyRated); - } else { - - } + } else {} } openInvoice() { diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index 49337ee4..f6d687d2 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -1,10 +1,14 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:provider/provider.dart'; import 'ClinicTimingsDialog.dart'; @@ -32,43 +36,118 @@ class _State extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return Container( width: double.infinity, margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 8.0), + clipBehavior: Clip.antiAlias, decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(10.0), + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(width: widget.isSelected ? 3 : 0, color: widget.isSelected ? CustomColors.green : Colors.transparent), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), - border: Border.all(width: 2, color: widget.isSelected ? CustomColors.green : Color(0xffEFEFEF)), - boxShadow: [ - BoxShadow( - color: Color(0xff000000).withOpacity(.05), - blurRadius: 27, - offset: Offset(0, -3), - ), - ], - color: Colors.white), + ], + color: Colors.transparent, + ), child: Container( - padding: EdgeInsets.fromLTRB(12.0, 25.0, 12.0, 25.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - child: Text(widget.languageID == 'ar' ? widget.patientERGetClinicsList.serviceNameN : widget.patientERGetClinicsList.serviceName, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16)), + decoration: BoxDecoration( + color: widget.patientERGetClinicsList.isOnline == 1 ? CustomColors.green : CustomColors.accentColor, + borderRadius: BorderRadius.all( + Radius.circular(6.0), + ), + ), + child: Container( + margin: EdgeInsets.only( + left: projectViewModel.isArabic + ? 0 + : widget.isSelected + ? 4 + : 6, + right: projectViewModel.isArabic ? widget.isSelected + ? 4 + : 6: 0), + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.only( + bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), ), - Row( - children: [ - Container( - child: Text(".", style: TextStyle(fontSize: 30.0)), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.languageID == 'ar' ? widget.patientERGetClinicsList.serviceNameN : widget.patientERGetClinicsList.serviceName, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.48, + ), + ), + Row( + children: [ + Container( + width: 4, + height: 4, + decoration: containerRadius( + widget.patientERGetClinicsList.isOnline == 1 ? CustomColors.green : CustomColors.accentColor, + 100, + ), + ), + mWidth(4), + Text( + widget.patientERGetClinicsList.isOnline == 1 ? "Online" : "Offline", + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: widget.patientERGetClinicsList.isOnline == 1 ? CustomColors.green : CustomColors.accentColor, + letterSpacing: -0.48, + ), + ), + ], + ), + ], ), - Container( - child: Text("Online"), + ), + Container( + padding: EdgeInsets.only(left: 8,right: 8,top: 4,bottom: 4), + decoration: containerRadius(CustomColors.devider, 100), + child: Row( + children: [ + SvgPicture.asset( + "assets/images/new-design/ic_schedule.svg", + width: 16, + height: 16, + color: Colors.black, + ), + mWidth(4), + Text( + "Schedule", + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ) + ], ), - ], - ), - ], + ), + ], + ), ), ), ); diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 9a463150..2127cd57 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -89,7 +89,9 @@ class _clinic_listState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView(child: currentSelectedLiveCareType == "immediate" ? getLiveCareImmediateClinicList() : getLiveCareScheduleClinicList()); + return Container( + child: currentSelectedLiveCareType == "immediate" ? getLiveCareImmediateClinicList() : getLiveCareScheduleClinicList(), + ); } void startLiveCare() { @@ -502,69 +504,70 @@ class _clinic_listState extends State { return Column( children: [ isDataLoaded - ? Container( - height: MediaQuery.of(context).size.height * 0.75, - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: const EdgeInsets.only(top: 16.0), - itemCount: liveCareOnlineClinicsListResponse.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - updateSelectedIndex(liveCareOnlineClinicsListResponse[index]); - }, - child: ClinicCard( - isSelected: selectedClinicID == liveCareOnlineClinicsListResponse[index].serviceID ? true : false, - patientERGetClinicsList: liveCareOnlineClinicsListResponse[index], + ? Expanded( + child: Container( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: const EdgeInsets.only(top: 16.0), + itemCount: liveCareOnlineClinicsListResponse.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + updateSelectedIndex(liveCareOnlineClinicsListResponse[index]); + }, + child: ClinicCard( + isSelected: selectedClinicID == liveCareOnlineClinicsListResponse[index].serviceID ? true : false, + patientERGetClinicsList: liveCareOnlineClinicsListResponse[index], + languageID: languageID, + ), + ); + }, + ), + // Container( + // margin: EdgeInsets.all(15.0), + // child: Text(TranslationBase.of(context).offlineClinics, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + // ), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: liveCareOfflineClinicsListResponse.length, + itemBuilder: (context, index) { + return ClinicCard( + isSelected: selectedClinicID == liveCareOfflineClinicsListResponse[index].serviceID ? true : false, + patientERGetClinicsList: liveCareOfflineClinicsListResponse[index], languageID: languageID, - ), - ); - }, - ), - // Container( - // margin: EdgeInsets.all(15.0), - // child: Text(TranslationBase.of(context).offlineClinics, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - // ), - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: liveCareOfflineClinicsListResponse.length, - itemBuilder: (context, index) { - return ClinicCard( - isSelected: selectedClinicID == liveCareOfflineClinicsListResponse[index].serviceID ? true : false, - patientERGetClinicsList: liveCareOfflineClinicsListResponse[index], - languageID: languageID, - ); - }, - ), - Container( - height: 50.0, - ), - ], - )), + ); + }, + ), + Container( + height: 50.0, + ), + ], + )), + ), ) : Container(), isDataLoaded - ? Align( - alignment: FractionalOffset.bottomCenter, - child: Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - color: Colors.grey[100], - width: MediaQuery.of(context).size.width, - height: 50.0, - child: DefaultButton(TranslationBase.of(context).start, () { - startLiveCare(); - }), - ), - ) + ? Container( + + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(16), + child: DefaultButton( + TranslationBase.of(context).start, + () { + startLiveCare(); + }, + ), + ) : Container(), ], ); diff --git a/lib/pages/livecare/widgets/livecare_logs.dart b/lib/pages/livecare/widgets/livecare_logs.dart index 7b85afc2..8898faa6 100644 --- a/lib/pages/livecare/widgets/livecare_logs.dart +++ b/lib/pages/livecare/widgets/livecare_logs.dart @@ -30,7 +30,12 @@ class _LiveCareLogsState extends State { padding: EdgeInsets.all(0.0), itemCount: widget.erRequestHistoryList.length, itemBuilder: (context, index) { - return widget.erRequestHistoryList[index].callStatus < 4 ? Container() : LiveCareHistoryCard(erRequestHistoryList: widget.erRequestHistoryList[index]); + return widget.erRequestHistoryList[index].callStatus < 4 + ? Container() + : LiveCareHistoryCard( + erRequestHistoryList: widget.erRequestHistoryList[index], + isFirstOrLast: index==0?0:(index==widget.erRequestHistoryList.length-1)?1:2, + ); }, ), ) From cb69684bb864398847fbccb67ef812d06a2d0766 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 17:35:00 +0300 Subject: [PATCH 43/60] SessionID update --- lib/core/service/client/base_app_client.dart | 54 +++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 5abbe81e..584ed67d 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -10,7 +10,6 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -31,8 +30,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); /// onFailure: (String error, int statusCode) {}, /// body: Map(); /// -AuthenticatedUserObject authenticatedUserObject = - locator(); +AuthenticatedUserObject authenticatedUserObject = locator(); VitalSignService _vitalSignService = locator(); class BaseAppClient { @@ -102,7 +100,7 @@ class BaseAppClient { ? body['PatientOutSA'] : PATIENT_OUT_SA : PATIENT_OUT_SA; - body['SessionID'] = SESSION_ID; //getSe + body['SessionID'] = getSessionId(body['TokenID']); //getSe headers = { 'Content-Type': 'application/json', @@ -162,8 +160,8 @@ class BaseAppClient { // if (parsed != null) { // onSuccess(parsed, statusCode); // } else { - onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); - // logout(); + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + // logout(); // } } } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { @@ -466,7 +464,8 @@ class BaseAppClient { simplePost( String fullUrl, { - Map body, Map headers, + Map body, + Map headers, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, }) async { @@ -483,8 +482,7 @@ class BaseAppClient { final int statusCode = response.statusCode; print("statusCode :$statusCode"); - if(await handleUnauthorized(statusCode, forUrl: fullUrl)) - simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -496,7 +494,8 @@ class BaseAppClient { } } - simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { + simpleGet(String fullUrl, + {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { String url = fullUrl; print("URL Query String: $url"); @@ -516,8 +515,7 @@ class BaseAppClient { final int statusCode = response.statusCode; print("statusCode :$statusCode"); - if(await handleUnauthorized(statusCode, forUrl: fullUrl)) - simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -543,8 +541,7 @@ class BaseAppClient { final int statusCode = response.statusCode; print("statusCode :$statusCode"); - if(await handleUnauthorized(statusCode, forUrl: fullUrl)) - simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -556,7 +553,8 @@ class BaseAppClient { } } - simpleDelete(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { + simpleDelete(String fullUrl, + {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { String url = fullUrl; print("URL Query String: $url"); @@ -576,8 +574,7 @@ class BaseAppClient { final int statusCode = response.statusCode; print("statusCode :$statusCode"); - if(await handleUnauthorized(statusCode, forUrl: fullUrl)) - simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); @@ -589,13 +586,13 @@ class BaseAppClient { } } - Future handleUnauthorized(int statusCode, {String forUrl}) async{ - if(forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { - final token = await generatePackagesToken(); - packagesAuthHeader['Authorization'] = 'Bearer $token'; - return token != null && (token is String); - } - return false; + Future handleUnauthorized(int statusCode, {String forUrl}) async { + if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { + final token = await generatePackagesToken(); + packagesAuthHeader['Authorization'] = 'Bearer $token'; + return token != null && (token is String); + } + return false; } logout() async { @@ -726,7 +723,7 @@ class BaseAppClient { print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { var parsed = json.decode(utf8.decode(response.bodyBytes)); - onFailure(parsed['error']['ErrorEndUserMsg'] ??'Error While Fetching data', statusCode); + onFailure(parsed['error']['ErrorEndUserMsg'] ?? 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -791,15 +788,10 @@ class BaseAppClient { } } - - Future generatePackagesToken() async { var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN; var body = { - "api_client": { - "client_id": "a4ab6be4-424f-4836-b032-46caed88e184", - "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c" - } + "api_client": {"client_id": "a4ab6be4-424f-4836-b032-46caed88e184", "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"} }; String token; final completer = Completer(); From 7123ed34ab70547792d266b5c037e49c8ed31a0a Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 27 Oct 2021 17:43:49 +0300 Subject: [PATCH 44/60] Translation updates --- lib/config/localized_values.dart | 2 ++ lib/pages/livecare/widgets/clinic_card.dart | 5 +++-- lib/uitl/translations_delegate_base.dart | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 0b74ff3c..4eafcd23 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1603,4 +1603,6 @@ const Map localizedValues = { "android-instructions-2": { "en": "Make sure that you have installed your watch related apps from Google PlayStore.", "ar": "تأكد من أنك قمت بتثبيت التطبيقات المتعلقة بالساعات من Google PlayStore." }, "android-instructions-3": { "en": "Make sure that your Smart Watch is connected with the WearOS app & your watch apps.", "ar": "تأكد من أن ساعتك الذكية متصلة بتطبيق WearOS وتطبيقات ساعتك." }, "android-instructions-4": { "en": "Make sure that your smart watch apps are linked/associated with Google Fit App.", "ar": "تأكد من أن تطبيقات ساعتك الذكية مرتبطة / مرتبطة بتطبيق Google Fit." }, "android-instructions-5": { "en": "Make sure that data like heart rate, steps, distance etc. are being shown on your watch app & on Google Fit app & both are in sync.", "ar": "تأكد من عرض بيانات مثل معدل ضربات القلب والخطوات والمسافة وما إلى ذلك على تطبيق الساعة وعلى تطبيق Google Fit وكلاهما في حالة مزامنة." }, + "onlineTag": {"en": "Online", "ar": "متصل"}, + "offlineTag": {"en": "Offline", "ar": "غير متصل"}, }; diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index f6d687d2..e788a5cd 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/services/livecare_services/livecare_provide import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; @@ -110,7 +111,7 @@ class _State extends State { ), mWidth(4), Text( - widget.patientERGetClinicsList.isOnline == 1 ? "Online" : "Offline", + widget.patientERGetClinicsList.isOnline == 1 ? TranslationBase.of(context).onlineTag : TranslationBase.of(context).offlineTag, style: TextStyle( fontSize: 10, fontWeight: FontWeight.w600, @@ -136,7 +137,7 @@ class _State extends State { ), mWidth(4), Text( - "Schedule", + TranslationBase.of(context).schedule, style: TextStyle( fontSize: 11, letterSpacing: -0.44, diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 396afd00..cefeeec2 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2563,6 +2563,10 @@ class TranslationBase { String get androidInstructions3 => localizedValues["android-instructions-3"][locale.languageCode]; String get androidInstructions4 => localizedValues["android-instructions-4"][locale.languageCode]; + + String get onlineTag => localizedValues["onlineTag"][locale.languageCode]; + + String get offlineTag => localizedValues["offlineTag"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 73822300f949f5034573f50a2c8843f4c0db5bc4 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 28 Oct 2021 10:46:09 +0300 Subject: [PATCH 45/60] Health Calculators APIs updated --- lib/config/localized_values.dart | 2 + .../health-calculator/bariatrics-service.dart | 11 +++ .../bmi_calculator/bariatrics-screen.dart | 92 ++++++++++++++++--- .../bmr_calculator/bmr_calculator.dart | 5 +- .../bmr_calculator/bmr_result_page.dart | 72 +++++++++++++-- .../health_calculator/body_fat/body_fat.dart | 7 +- .../body_fat/body_fat_result_page.dart | 73 +++++++++++++-- .../calorie_result_page.dart | 69 ++++++++++++-- .../health_calculator/carbs/carbs.dart | 7 +- .../carbs/carbs_result_page.dart | 82 +++++++++++++---- .../ideal_body/ideal_body.dart | 6 +- .../ideal_body/ideal_body_result_page.dart | 82 ++++++++++++++--- lib/uitl/translations_delegate_base.dart | 4 + 13 files changed, 442 insertions(+), 70 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 4eafcd23..810c4156 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1605,4 +1605,6 @@ const Map localizedValues = { "android-instructions-4": { "en": "Make sure that your smart watch apps are linked/associated with Google Fit App.", "ar": "تأكد من أن تطبيقات ساعتك الذكية مرتبطة / مرتبطة بتطبيق Google Fit." }, "android-instructions-5": { "en": "Make sure that data like heart rate, steps, distance etc. are being shown on your watch app & on Google Fit app & both are in sync.", "ar": "تأكد من عرض بيانات مثل معدل ضربات القلب والخطوات والمسافة وما إلى ذلك على تطبيق الساعة وعلى تطبيق Google Fit وكلاهما في حالة مزامنة." }, "onlineTag": {"en": "Online", "ar": "متصل"}, "offlineTag": {"en": "Offline", "ar": "غير متصل"}, + "viewDocList": {"en": "View List of Doctors", "ar": "عرض قائمة الأطباء"}, + "bodyFatTitle": {"en": "Body Fat", "ar": " الدهون في الجسم"}, }; diff --git a/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart index c952a88f..139c251b 100644 --- a/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart +++ b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart @@ -13,6 +13,9 @@ class BariatricsService extends BaseService { List doctorList = []; List doctorListByTime = []; + double lat; + double long; + Future getClinicCategory() async { hasError = false; Map body = Map(); @@ -104,12 +107,20 @@ class BariatricsService extends BaseService { } Future getCalculationDoctors({@required int calculationID}) async { + + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + lat = await this.sharedPref.getDouble(USER_LAT); + long = await this.sharedPref.getDouble(USER_LONG); + } + hasError = false; var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Map body = Map(); body['CalculationID'] = calculationID; // hint: it is static depend on IONIC project body['LanguageID'] = languageID == 'ar' ? 1 : 2; + body['Latitude'] = lat != null ? lat.toString() : 0; + body['Longitude'] = long != null ? long.toString() : 0; dynamic localRes; diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart index ae7a35a7..13de0140 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart @@ -1,9 +1,15 @@ +import 'dart:collection'; + import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -61,9 +67,7 @@ class _BariatricsPageState extends State { activeColor: Colors.blue.shade700, value: item.diseasesID, groupValue: _selectedDisease != null ? _selectedDisease.diseasesID : -1, - selected: _selectedDisease != null - ? item.diseasesID == _selectedDisease.diseasesID - : false, + selected: _selectedDisease != null ? item.diseasesID == _selectedDisease.diseasesID : false, onChanged: (val) { setState(() { _selectedDisease = item; @@ -95,10 +99,14 @@ class _BariatricsPageState extends State { radius: 8, fontWeight: FontWeight.bold, handler: () async { - Navigator.push( - context, - FadePage(page: DoctorList(diseaseByClinic: _selectedDisease,)), - ); + callDoctorsSearchAPI(); + // Navigator.push( + // context, + // FadePage( + // page: DoctorList( + // diseaseByClinic: _selectedDisease, + // )), + // ); }, ), ), @@ -116,10 +124,11 @@ class _BariatricsPageState extends State { borderColor: Color(0x00000000), fontWeight: FontWeight.bold, handler: () async { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + callDoctorsSearchAPI(); + // Navigator.push( + // context, + // FadePage(page: DoctorList()), + // ); }, ), ), @@ -129,6 +138,65 @@ class _BariatricsPageState extends State { ); } + callDoctorsSearchAPI() { + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = List(); + + DoctorsListService service = new DoctorsListService(); + service.getDoctorsList(108, 0, false, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + if (res['DoctorList'].length != 0) { + doctorsList.clear(); + res['DoctorList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson(v)); + }); + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital + .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); + } + }); + } else {} + }); + + result = LinkedHashSet.from(arr).toList(); + numAll = result.length; + navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + }); + } + + Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) + .then((value) { + setState(() { + // dropdownValue = null; + }); + // getProjectsList(); + }); + } + _getImageName(int gender, double obeseResult, bool isArabic) { String path = "assets/images/BMI/"; double result = obeseResult; diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart index 0e22c7ae..ad35c61d 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart @@ -1,4 +1,5 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -123,7 +124,9 @@ class _BmrCalculatorState extends State { return AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: 'Bmr Calculator', + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bmr, showHomeAppBarIcon: false, appBarIcons: [ Padding( diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart index 6e7d6279..e1409ee5 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart @@ -1,4 +1,8 @@ -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -9,13 +13,17 @@ import 'package:percent_indicator/circular_percent_indicator.dart'; class BmrResultPage extends StatelessWidget { final double bmrResult; final double calories; + BmrResultPage({this.bmrResult, this.calories}); + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: 'BMR Calculator', + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bmr, body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -58,16 +66,66 @@ class BmrResultPage extends StatelessWidget { Container( width: 350, child: Button( - label: 'See List Of Doctors', + label: TranslationBase.of(context).viewDocList, onTap: () { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + getDoctorsList(context); }), ), ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = List(); + + service.getCalculationDoctors(calculationID: 3).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['List_CalculationTable'].length); + if (res['MessageStatus'] == 1) { + if (res['List_CalculationTable'].length != 0) { + res['List_CalculationTable'].forEach((item) { + DoctorList docList = new DoctorList(); + docList.clinicID = item['ClinicID']; + docList.clinicName = item['ClinicName']; + docList.doctorID = item['DoctorID']; + docList.doctorImageURL = item['DoctorImageURL']; + docList.name = item['DoctorName']; + docList.doctorTitle = item['DoctorTitle']; + docList.gender = item['Gender']; + docList.genderDescription = item['GenderDescription']; + docList.nationalityName = item['Nationality']; + docList.nationalityFlagURL = item['NationalityFlagURL']; + docList.projectID = item['ProjectID']; + docList.projectName = item['ProjectName']; + docList.actualDoctorRate = 0; + doctorsList.add(docList); + }); + + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: "0", patientDoctorAppointment: element)); + } + }); + + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart index afbc9f1c..7b32c840 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -210,8 +211,10 @@ class _BodyFatState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Body Fat', - showHomeAppBarIcon: false, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bodyFatTitle, appBarIcons: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), diff --git a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart index f41f9598..9ba23a1e 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart @@ -1,4 +1,8 @@ -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -12,7 +16,9 @@ class FatResult extends StatelessWidget { final String textResult; FatResult({this.bodyFat, this.fat, this.textResult = ''}); + Color inductorColor; + Color colorInductor() { if (bodyFat >= 17) { inductorColor = Color(0xffC70D00); @@ -30,7 +36,10 @@ class FatResult extends StatelessWidget { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Body Fat', + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bodyFatTitle, body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -69,12 +78,9 @@ class FatResult extends StatelessWidget { Container( width: 350, child: Button( - label: 'See List Of Doctors', + label: TranslationBase.of(context).viewDocList, onTap: () { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + getDoctorsList(context); }, ), ), @@ -82,4 +88,57 @@ class FatResult extends StatelessWidget { ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = List(); + + service.getCalculationDoctors(calculationID: 5).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['List_CalculationTable'].length); + if (res['MessageStatus'] == 1) { + if (res['List_CalculationTable'].length != 0) { + res['List_CalculationTable'].forEach((item) { + DoctorList docList = new DoctorList(); + docList.clinicID = item['ClinicID']; + docList.clinicName = item['ClinicName']; + docList.doctorID = item['DoctorID']; + docList.doctorImageURL = item['DoctorImageURL']; + docList.name = item['DoctorName']; + docList.doctorTitle = item['DoctorTitle']; + docList.gender = item['Gender']; + docList.genderDescription = item['GenderDescription']; + docList.nationalityName = item['Nationality']; + docList.nationalityFlagURL = item['NationalityFlagURL']; + docList.projectID = item['ProjectID']; + docList.projectName = item['ProjectName']; + docList.actualDoctorRate = 0; + doctorsList.add(docList); + }); + + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: "0", patientDoctorAppointment: element)); + } + }); + + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart index ed3dd8f8..749bf241 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart @@ -1,4 +1,7 @@ -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -15,9 +18,11 @@ class CalorieResultPage extends StatelessWidget { @override Widget build(BuildContext context) { return AppScaffold( - isShowDecPage: false, appBarTitle: "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calculators}", isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -52,12 +57,9 @@ class CalorieResultPage extends StatelessWidget { Container( width: 350, child: Button( - label: 'See List Of Doctors', + label: TranslationBase.of(context).viewDocList, onTap: () { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + getDoctorsList(context); }, ), ), @@ -65,4 +67,57 @@ class CalorieResultPage extends StatelessWidget { ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = List(); + + service.getCalculationDoctors(calculationID: 2).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['List_CalculationTable'].length); + if (res['MessageStatus'] == 1) { + if (res['List_CalculationTable'].length != 0) { + res['List_CalculationTable'].forEach((item) { + DoctorList docList = new DoctorList(); + docList.clinicID = item['ClinicID']; + docList.clinicName = item['ClinicName']; + docList.doctorID = item['DoctorID']; + docList.doctorImageURL = item['DoctorImageURL']; + docList.name = item['DoctorName']; + docList.doctorTitle = item['DoctorTitle']; + docList.gender = item['Gender']; + docList.genderDescription = item['GenderDescription']; + docList.nationalityName = item['Nationality']; + docList.nationalityFlagURL = item['NationalityFlagURL']; + docList.projectID = item['ProjectID']; + docList.projectName = item['ProjectName']; + docList.actualDoctorRate = 0; + doctorsList.add(docList); + }); + + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: "0", patientDoctorAppointment: element)); + } + }); + + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart index 7d8f4655..4b68687a 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -81,8 +82,10 @@ class _CarbsState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Carb Protein Fat', - showHomeAppBarIcon: false, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).carbohydrate, appBarIcons: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), diff --git a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart index 71055d7b..46c14ee0 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart @@ -1,5 +1,9 @@ -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -32,7 +36,10 @@ class CarbsResult extends StatelessWidget { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Carb Protein Fat', + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).carbohydrate, body: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -156,27 +163,68 @@ class CarbsResult extends StatelessWidget { Container( width: 350, child: Button( - label: 'See List Of Doctors', + label: TranslationBase.of(context).viewDocList, onTap: () { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + getDoctorsList(context); }, ), ), ], ), - - // Texts(pCal.ceil().toString()), - // Texts(cCal.ceil().toString()), - // Texts(fCal.ceil().toString()), - // Texts(pCalGram.ceil().toString()), - // Texts(cCalGram.ceil().toString()), - // Texts(fCalGram.ceil().toString()), - // Texts(pCalMeal.ceil().toString()), - // Texts(cCalMeal.ceil().toString()), - // Texts(fCalMeal.ceil().toString()), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = List(); + + service.getCalculationDoctors(calculationID: 11).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['List_CalculationTable'].length); + if (res['MessageStatus'] == 1) { + if (res['List_CalculationTable'].length != 0) { + res['List_CalculationTable'].forEach((item) { + DoctorList docList = new DoctorList(); + docList.clinicID = item['ClinicID']; + docList.clinicName = item['ClinicName']; + docList.doctorID = item['DoctorID']; + docList.doctorImageURL = item['DoctorImageURL']; + docList.name = item['DoctorName']; + docList.doctorTitle = item['DoctorTitle']; + docList.gender = item['Gender']; + docList.genderDescription = item['GenderDescription']; + docList.nationalityName = item['Nationality']; + docList.nationalityFlagURL = item['NationalityFlagURL']; + docList.projectID = item['ProjectID']; + docList.projectName = item['ProjectName']; + docList.actualDoctorRate = 0; + doctorsList.add(docList); + }); + + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: "0", patientDoctorAppointment: element)); + } + }); + + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart index 84f76153..e8d89b13 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart @@ -1,4 +1,5 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -100,7 +101,10 @@ class _IdealBodyState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Ideal Body Weight', + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).idealBody, showHomeAppBarIcon: false, appBarIcons: [ Padding( diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart index 311b423a..6a40bee7 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart @@ -1,5 +1,8 @@ - -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/doctor_list.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -14,11 +17,15 @@ class IdealBodyResult extends StatelessWidget { final String textResult; IdealBodyResult({this.idealBodyWeight, this.minRange, this.mixRange, this.overWeightBy, this.textResult}); + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Ideal Body Weight', + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).idealBody, body: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -81,8 +88,7 @@ class IdealBodyResult extends StatelessWidget { children: [ Texts('This means that the weight is a little bit more than ideal weight by'), Texts(overWeightBy.toStringAsFixed(1)), - Texts( - 'May wish to consult with the doctor for medical help. Click to view our list of Doctors'), + Texts('May wish to consult with the doctor for medical help. Click to view our list of Doctors'), ], ) : overWeightBy >= 18 @@ -104,8 +110,7 @@ class IdealBodyResult extends StatelessWidget { SizedBox( height: 25.0, ), - Texts( - 'May wish to consult with the doctor for\n medical help. Click to view our list of\n Doctors'), + Texts('May wish to consult with the doctor for\n medical help. Click to view our list of\n Doctors'), ], ), ) @@ -148,20 +153,16 @@ class IdealBodyResult extends StatelessWidget { SizedBox( height: 25.0, ), - Texts( - 'May wish to consult with the doctor for\n medical help. Click to view our list of\n Doctors'), + Texts('May wish to consult with the doctor for\n medical help. Click to view our list of\n Doctors'), ], ), ), Container( width: 350, child: Button( - label: 'See List Of Doctors', + label: TranslationBase.of(context).viewDocList, onTap: () { - Navigator.push( - context, - FadePage(page: DoctorList()), - ); + getDoctorsList(context); }, ), ), @@ -169,4 +170,57 @@ class IdealBodyResult extends StatelessWidget { ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = List(); + + service.getCalculationDoctors(calculationID: 4).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['List_CalculationTable'].length); + if (res['MessageStatus'] == 1) { + if (res['List_CalculationTable'].length != 0) { + res['List_CalculationTable'].forEach((item) { + DoctorList docList = new DoctorList(); + docList.clinicID = item['ClinicID']; + docList.clinicName = item['ClinicName']; + docList.doctorID = item['DoctorID']; + docList.doctorImageURL = item['DoctorImageURL']; + docList.name = item['DoctorName']; + docList.doctorTitle = item['DoctorTitle']; + docList.gender = item['Gender']; + docList.genderDescription = item['GenderDescription']; + docList.nationalityName = item['Nationality']; + docList.nationalityFlagURL = item['NationalityFlagURL']; + docList.projectID = item['ProjectID']; + docList.projectName = item['ProjectName']; + docList.actualDoctorRate = 0; + doctorsList.add(docList); + }); + + doctorsList.forEach((element) { + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: "0", patientDoctorAppointment: element)); + } + }); + + Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: doctorsList, patientDoctorAppointmentListHospital: _patientDoctorAppointmentListHospital))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index cefeeec2..50a90f39 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2567,6 +2567,10 @@ class TranslationBase { String get onlineTag => localizedValues["onlineTag"][locale.languageCode]; String get offlineTag => localizedValues["offlineTag"][locale.languageCode]; + + String get viewDocList => localizedValues["viewDocList"][locale.languageCode]; + + String get bodyFatTitle => localizedValues["bodyFatTitle"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 2a212149ed069c2c29e48b5f15fa287a6a3bbf60 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 28 Oct 2021 13:50:40 +0300 Subject: [PATCH 46/60] Health converters UI done --- lib/config/localized_values.dart | 3 +- .../health_converter.dart | 18 +- .../health_converter/blood_cholesterol.dart | 393 +++++++++-------- .../health_converter/blood_sugar.dart | 367 ++++++++-------- .../health_converter/triglycerides.dart | 397 ++++++++++-------- .../​ health_calculators.dart | 4 +- .../components/SearchByDoctor.dart | 10 - lib/uitl/translations_delegate_base.dart | 3 + 8 files changed, 622 insertions(+), 573 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 810c4156..05bc4b52 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1144,7 +1144,7 @@ const Map localizedValues = { "ar": "تحويل مستوى السكر في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" }, "convertCholesterolStatement": { - "en": "Convert blood cholesterol from\n mmol/l to mg/dlt and vice versa.", + "en": "Convert blood cholesterol from mmol/l to mg/dlt and vice versa.", "ar": "تحويل مستوى الكولسترول في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" }, "triglyceridesConvertStatement": { @@ -1607,4 +1607,5 @@ const Map localizedValues = { "offlineTag": {"en": "Offline", "ar": "غير متصل"}, "viewDocList": {"en": "View List of Doctors", "ar": "عرض قائمة الأطباء"}, "bodyFatTitle": {"en": "Body Fat", "ar": " الدهون في الجسم"}, + "cholesTitle": {"en": "Blood Cholesterol", "ar": " الكولسترول في الدم"}, }; diff --git a/lib/pages/AlHabibMedicalService/health_converter.dart b/lib/pages/AlHabibMedicalService/health_converter.dart index 27c2a05c..c4ad7760 100644 --- a/lib/pages/AlHabibMedicalService/health_converter.dart +++ b/lib/pages/AlHabibMedicalService/health_converter.dart @@ -26,12 +26,8 @@ class _HealthConverterState extends State { appBarTitle: TranslationBase.of(context).converters, body: Column( children: [ - Container( - width: double.infinity, - height: 30, - ), Padding( - padding: EdgeInsets.only(left: 12, right: 12), + padding: EdgeInsets.only(left: 12, right: 12, top: 20.0), child: GridView.builder( shrinkWrap: true, primary: false, @@ -59,9 +55,9 @@ class _HealthConverterState extends State { ), child: MedicalProfileItem( title: TranslationBase.of(context).bloodSugar, - imagePath: 'assets/images/new-design/blood_sugar_icon.png', + imagePath: 'sugar-blood-level.svg', subTitle: TranslationBase.of(context).sugar, - isPngImage: true, + isPngImage: false, ), )); @@ -72,9 +68,9 @@ class _HealthConverterState extends State { ), child: MedicalProfileItem( title: TranslationBase.of(context).bloodCholesterol, - imagePath: 'assets/images/new-design/blood_cholesterol_icon.png', + imagePath: 'cholesterol.svg', subTitle: TranslationBase.of(context).cholesterol, - isPngImage: true, + isPngImage: false, ), )); @@ -85,9 +81,9 @@ class _HealthConverterState extends State { ), child: MedicalProfileItem( title: TranslationBase.of(context).triglycerides, - imagePath: 'assets/images/new-design/triglycerides_blood_icon.png', + imagePath: 'fat.svg', subTitle: TranslationBase.of(context).fatInBlood, - isPngImage: true, + isPngImage: false, ), )); return medical; diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart index 5e584602..af93afa4 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart @@ -1,12 +1,13 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -const activeCardColor = Color(0xffD02127); -const inactiveCardColor = Color(0xffFAFAFd); +const activeCardColor = CustomColors.green; +const inactiveCardColor = CustomColors.white; class BloodCholesterol extends StatefulWidget { @override @@ -18,7 +19,6 @@ class _BloodCholesterolState extends State { Color cardMMOLColor = inactiveCardColor; void updateColor(int type) { - //MG/DLT card if (type == 1) { if (cardMGColor == inactiveCardColor) { cardMGColor = activeCardColor; @@ -51,225 +51,246 @@ class _BloodCholesterolState extends State { bool _visible = false; TextEditingController textController = new TextEditingController(); + TextEditingController resultTextController = new TextEditingController(); String finalValue; double inputValue = 0.0; String unit; double conversionConst = 38.67; + @override + void initState() { + updateColor(1); + unit = 'mmol/l'; + super.initState(); + } + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).bloodCholesterol, + appBarTitle: TranslationBase.of(context).cholesTitle, isShowDecPage: false, showNewAppBar: true, showNewAppBarTitle: true, body: Padding( padding: const EdgeInsets.all(16.0), - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.7, - child: Column( - //crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 350.0, - child: Text( - TranslationBase.of(context).convertCholesterolStatement, - style: TextStyle(fontSize: 20.0), - ), - ), - SizedBox( - height: 15.0, - ), - Container( - color: Colors.white, - height: 120.0, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container(child: Text(TranslationBase.of(context).cholesTitle, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).convertCholesterolStatement, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + SizedBox( + height: 13.0, + ), + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Text(TranslationBase.of(context).convertFrom, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + SizedBox( + height: 9.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 15.0), - child: Row( - children: [ - Texts( - TranslationBase.of(context).convertFrom, + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + inputValue = double.parse(textController.text); + inputValue = inputValue / conversionConst; + unit = 'mmol/l'; + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), + ), + border: Border.all(width: 2, color: cardMGColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white, ), - ], + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text('MG/DLt to MMOL/L', + textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + ), ), ), SizedBox( - height: 9.0, + width: 12.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - inputValue = - double.parse(textController.text); - inputValue = inputValue / conversionConst; - unit = 'mmol/l'; - }); - }, - child: Container( - height: 65.0, - width: 150.0, - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow - ), - ], - color: cardMGColor, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Texts('MG/DLt TO \nMMOL/L'), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + inputValue = double.parse(textController.text); + inputValue = inputValue * conversionConst; + unit = 'mg/dlt'; + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), ), + border: Border.all(width: 2, color: cardMMOLColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white, ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - inputValue = - double.parse(textController.text); - inputValue = inputValue * conversionConst; - unit = 'mg/dlt'; - }); - }, - child: Container( - height: 65.0, - width: 150.0, - decoration: BoxDecoration( - color: cardMMOLColor, - borderRadius: BorderRadius.circular(3.0), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow - ), - ], - ), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0), - child: Texts('MG/DLt TO\n MMOL/L'), - ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text('MMOL/L to MG/DLt', + textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), ), ), - ], + ), ), ], ), - ), + ], ), - SizedBox( - height: 25.0, - ), - Container( - height: 65.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Colors.white, + ), + SizedBox( + height: 12.0, + ), + inputWidget(TranslationBase.of(context).enterReadingValue, '0.0', textController), + SizedBox( + height: 12.0, + ), + Visibility( + visible: _visible, + child: inputWidget(TranslationBase.of(context).result, inputValue.toStringAsFixed(2) + " " + unit.toString(), resultTextController, isEnable: false), + ), + SizedBox( + height: 15.0, + ), + ], + ), + ), + ), + bottomSheet: Container( + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 1.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).calculate, + () { + setState(() { + _visible == false ? _visible = !_visible : _visible = _visible; + calculateBloodCholesterol(); + }); + }, + color: CustomColors.green, + ), + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: isEnable ? Colors.white : CustomColors.grey2.withOpacity(0.4), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), ), - child: TextFormField( - controller: textController, - inputFormatters: [ -// FilteringTextInputFormatter.digitsOnly - ], + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, keyboardType: TextInputType.number, + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45)), - labelText: TranslationBase.of(context).enterReadingValue, - labelStyle: TextStyle( - color: Colors.black87, + isDense: true, + hintText: _hintText, + fillColor: CustomColors.accentColor, + hintStyle: TextStyle( + fontSize: isEnable ? 14 : 24, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: isEnable ? Color(0xff575757) : CustomColors.black, + letterSpacing: -0.56, ), - ), - ), - ), - SizedBox( - height: 25.0, - ), - Visibility( - visible: _visible, - child: Container( - height: 115.0, - width: 350.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.black), - borderRadius: BorderRadius.circular(15.0), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Texts(TranslationBase.of(context).result + ":"), - Row( - children: [ - Text( - inputValue.toStringAsFixed(3).toString(), - style: TextStyle(fontSize: 35.0), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, ), - Padding( - padding: EdgeInsets.only(left: 4.0, top: 10.0), - child: Text( - unit.toString(), - style: TextStyle( - color: Color(0xffC5273A), - fontSize: 15.0, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ], - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Flexible( - child: Container( - height: 60.0, - width: 150.0, - child: SecondaryButton( - label: TranslationBase.of(context).calculate, - onTap: () { - setState(() { - _visible == false - ? _visible = !_visible - : _visible = _visible; - calculateBloodCholesterol(); - }); - }, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), ), - ), - ], + ], + ), ), - ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart index ebc41150..4604c3df 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart @@ -1,15 +1,15 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -const activeCardColor = Color(0xffD02127); -const activeTextColor = Color(0xffFAFAFA); -const inactiveCardColor = Color(0xffFAFAFA); -const inactiveTextColor = Color(0xff60686B); +const activeCardColor = CustomColors.green; +const activeTextColor = CustomColors.black; +const inactiveCardColor = CustomColors.white; +const inactiveTextColor = CustomColors.black; class BloodSugar extends StatefulWidget { @override @@ -25,7 +25,6 @@ class _BloodSugarState extends State { Color textMMOLColor = inactiveTextColor; void updateColor(int type) { - //MG/DLT card if (type == 1) { if (cardMGColor == inactiveCardColor) { cardMGColor = activeCardColor; @@ -59,10 +58,12 @@ class _BloodSugarState extends State { inputValue = inputValue * 18; unit = 'mg/dlt'; } + setState(() {}); } bool _visible = false; TextEditingController textController = new TextEditingController(); + TextEditingController resultTextController = new TextEditingController(); String finalValue; double inputValue = 0; @@ -90,210 +91,222 @@ class _BloodSugarState extends State { Expanded( child: SingleChildScrollView( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container(child: Text(TranslationBase.of(context).bloodSugar, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), Container( - margin: EdgeInsets.symmetric(horizontal: 8), - child: Text( - TranslationBase.of(context).convertBloodSugarStatement, - style: TextStyle(fontSize: 20.0), - ), + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).convertBloodSugarStatement, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), ), SizedBox( height: 12.0, ), Container( - color: Colors.white, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - children: [ - Texts( - TranslationBase.of(context).convertFrom, - ) - ], - ), - ), - SizedBox( - height: 8.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: 16.0, - ), - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColor(1); - calculateBloodSugar(); - }); - }, - child: Container( - height: 65.0, - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 7, - offset: Offset(0, 3), // changes position of shadow - ), - ], - color: cardMGColor, - borderRadius: BorderRadius.circular(3.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Text(TranslationBase.of(context).convertFrom, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + SizedBox( + height: 8.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + calculateBloodSugar(); + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), ), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 0.0, horizontal: 18.0), - child: Texts( - 'MG/DLt TO \nMMOL/L', - color: textMGColor, + border: Border.all(width: 2, color: cardMGColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), + ], + color: Colors.white, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'MG/DLt to MMOL/L', + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey), ), ), ), ), - SizedBox( - width: 12.0, - ), - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColor(2); - calculateBloodSugar(); - }); - }, - child: Container( - height: 65.0, - decoration: BoxDecoration( - color: cardMMOLColor, - borderRadius: BorderRadius.circular(3.0), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset(0, 3), // changes position of shadow - ), - ], + ), + SizedBox( + width: 12.0, + ), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + calculateBloodSugar(); + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Texts( - 'MMOL/L TO MG/DLt ', - color: textMMOLColor, + border: Border.all(width: 2, color: cardMMOLColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), + ], + color: Colors.white, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'MMOL/L to MG/DLt', + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey), ), ), ), ), - SizedBox( - width: 16.0, - ), - ], - ), - ], - ), + ), + ], + ), + ], ), ), SizedBox( - height: 24.0, - ), - Container( - height: 65.0, - padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Colors.white, - ), - child: TextFormField( - controller: textController, - inputFormatters: [ -// FilteringTextInputFormatter.digitsOnly - ], - keyboardType: TextInputType.number, - decoration: InputDecoration( - labelText: TranslationBase.of(context).enterReadingValue, - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide(color: Colors.white), - ), - disabledBorder: UnderlineInputBorder( - borderSide: BorderSide(color: Colors.white), - ), - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide(color: Colors.white), - ), - border: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white)), - labelStyle: TextStyle( - color: Colors.black87, - ), - ), - ), + height: 12.0, ), + inputWidget(TranslationBase.of(context).enterReadingValue, '0.0', textController), SizedBox( - height: 24.0, + height: 12.0, ), Visibility( visible: _visible, - child: Container( - height: 115.0, - width: 350.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.black), - borderRadius: BorderRadius.circular(15.0), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Texts(TranslationBase.of(context).result + ": "), - Row( - children: [ - Text( - inputValue.toStringAsFixed(2), - style: TextStyle(fontSize: 35.0), - ), - Padding( - padding: EdgeInsets.only(left: 4.0, top: 10.0), - child: Text( - unit.toString(), - style: TextStyle( - color: Color(0xffC5273A), - fontSize: 15.0, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ], - ), - ), - ), + child: inputWidget(TranslationBase.of(context).result, inputValue.toStringAsFixed(2) + " " + unit.toString(), resultTextController, isEnable: false), ), ], ), ), ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16), - child: DefaultButton(TranslationBase.of(context).calculate, () { - setState(() { - _visible == false ? _visible = !_visible : _visible = _visible; - calculateBloodSugar(); - }); - }), + ], + ), + ), + bottomSheet: Container( + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 1.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).calculate, + () { + setState(() { + _visible == false ? _visible = !_visible : _visible = _visible; + calculateBloodSugar(); + }); + }, + color: CustomColors.green, + ), + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: isEnable ? Colors.white : CustomColors.grey2.withOpacity(0.4), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.number, + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + fillColor: CustomColors.accentColor, + hintStyle: TextStyle( + fontSize: isEnable ? 14 : 24, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: isEnable ? Color(0xff575757) : CustomColors.black, + letterSpacing: -0.56, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), ], ), ), diff --git a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart index b9571d2b..e441d935 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart @@ -1,13 +1,13 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -const activeCardColor = Color(0xff70777A); -const inactiveCardColor = Color(0xffFAFAFd); +const activeCardColor = CustomColors.green; +const inactiveCardColor = CustomColors.white; class Triglycerides extends StatefulWidget { @override @@ -18,6 +18,7 @@ class _TriglyceridesState extends State { Color cardMGColor = inactiveCardColor; Color cardMMOLColor = inactiveCardColor; int type; + void updateColor(type) { //MG/DLT card if (type == 1) { @@ -52,12 +53,20 @@ class _TriglyceridesState extends State { bool _visible = false; TextEditingController textController = new TextEditingController(); + TextEditingController resultTextController = new TextEditingController(); String finalValue; double inputValue = 0.0; String unit; double conversionConst = 88.57; + @override + void initState() { + updateColor(1); + unit = 'mmol/l'; + super.initState(); + } + @override Widget build(BuildContext context) { return AppScaffold( @@ -68,210 +77,226 @@ class _TriglyceridesState extends State { showNewAppBarTitle: true, body: Padding( padding: const EdgeInsets.all(16.0), - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.7, - child: Column( - //crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 350.0, - child: Text( - TranslationBase.of(context).triglyceridesConvertStatement, - //textAlign: TextAlign.center, - style: TextStyle(fontSize: 20.0), - ), - ), - SizedBox( - height: 15.0, - ), - Container( - color: Colors.white, - height: 120.0, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - //crossAxisAlignment: CrossAxisAlignment.end, + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container(child: Text(TranslationBase.of(context).triglycerides, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: + Text(TranslationBase.of(context).triglyceridesConvertStatement, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + SizedBox( + height: 12.0, + ), + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Text(TranslationBase.of(context).convertFrom, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + ), + SizedBox( + height: 9.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 15.0), - child: Row( - children: [ - Texts(TranslationBase.of(context).convertFrom) - ], + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + inputValue = double.parse(textController.text); + inputValue = inputValue / conversionConst; + unit = 'mmol/l'; + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), + ), + border: Border.all(width: 2, color: cardMGColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'MG/DLt to MMOL/L', + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey), + ), + ), + ), ), ), SizedBox( - height: 9.0, + width: 12.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - inputValue = - double.parse(textController.text); - inputValue = inputValue / conversionConst; - unit = 'mmol/l'; - }); - }, - child: Container( - height: 65.0, - width: 150.0, - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow - ), - ], - color: cardMGColor, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Texts('MG/DLt TO \nMMOL/L'), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + inputValue = double.parse(textController.text); + inputValue = inputValue * conversionConst; + unit = 'mg/dlt'; + }); + }, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0), ), + border: Border.all(width: 2, color: cardMMOLColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white, ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - inputValue = - double.parse(textController.text); - inputValue = inputValue * conversionConst; - unit = 'mg/dlt'; - }); - }, - child: Container( - height: 65.0, - width: 150.0, - decoration: BoxDecoration( - color: cardMMOLColor, - borderRadius: BorderRadius.circular(3.0), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow - ), - ], - ), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0), - child: Texts('MG/DLt TO\n MMOL/L'), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'MMOL/L to MG/DLt', + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, letterSpacing: -0.64, color: CustomColors.darkGrey), ), ), ), - ], + ), ), ], ), - ), - ), - SizedBox( - height: 25.0, + ], ), - Container( - height: 65.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Colors.white, + ), + SizedBox( + height: 12.0, + ), + inputWidget(TranslationBase.of(context).enterReadingValue, "0.0", textController), + SizedBox( + height: 12.0, + ), + Visibility( + visible: _visible, + child: inputWidget(TranslationBase.of(context).result, inputValue.toStringAsFixed(2) + " " + unit.toString(), resultTextController, isEnable: false), + ), + ], + ), + ), + ), + bottomSheet: Container( + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 1.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).calculate.toUpperCase(), + () { + setState(() { + _visible == false ? _visible = !_visible : _visible = _visible; + calculateTriglycerides(); + }); + }, + color: CustomColors.green, + ), + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: isEnable ? Colors.white : CustomColors.grey2.withOpacity(0.4), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), ), - child: TextFormField( - controller: textController, - inputFormatters: [ -// FilteringTextInputFormatter.digitsOnly - ], + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, keyboardType: TextInputType.number, + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45)), - labelText: TranslationBase.of(context).enterReadingValue, - labelStyle: TextStyle( - color: Colors.black87, + isDense: true, + hintText: _hintText, + fillColor: CustomColors.accentColor, + hintStyle: TextStyle( + fontSize: isEnable ? 14 : 24, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: isEnable ? Color(0xff575757) : CustomColors.black, + letterSpacing: -0.56, ), - ), - ), - ), - SizedBox( - height: 25.0, - ), - Visibility( - visible: _visible, - child: Container( - height: 115.0, - width: 350.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.black), - borderRadius: BorderRadius.circular(15.0), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Texts(TranslationBase.of(context).result + ":"), - Row( - children: [ - Text( - inputValue.toStringAsFixed(2), - style: TextStyle(fontSize: 35.0), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, ), - Padding( - padding: EdgeInsets.only(left: 4.0, top: 10.0), - child: Text( - unit.toString(), - style: TextStyle( - color: Color(0xffC5273A), - fontSize: 15.0, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ], - ), - ), - ), - ), - SizedBox( - height: 10.0, - ), - Flexible( - child: Container( - height: 60.0, - width: 250.0, - child: SecondaryButton( - label: - TranslationBase.of(context).calculate.toUpperCase(), - onTap: () { - setState(() { - _visible == false - ? _visible = !_visible - : _visible = _visible; - calculateTriglycerides(); - }); - }, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), ), - ), - ], + ], + ), ), - ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/​ health_calculators.dart b/lib/pages/AlHabibMedicalService/​ health_calculators.dart index de4e3a48..341a298d 100644 --- a/lib/pages/AlHabibMedicalService/​ health_calculators.dart +++ b/lib/pages/AlHabibMedicalService/​ health_calculators.dart @@ -88,11 +88,11 @@ class _HealthCalculatorsState extends State with SingleTicker controller: _tabController, children: [ Container( - margin: EdgeInsets.all(20.0), + // margin: EdgeInsets.all(20.0), child: Column( children: [ Padding( - padding: EdgeInsets.only(left: 12, right: 12), + padding: EdgeInsets.only(left: 12, right: 12, top: 20.0), child: GridView.builder( shrinkWrap: true, primary: false, diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index 829ac0e2..6bfac9a7 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -46,17 +46,7 @@ class _SearchByDoctorState extends State { ), ), ), - // Container( - // decoration: BoxDecoration(color: Colors.white), - // child: TextField( - // controller: doctorNameController, - // onChanged: (content) { - // _onDocTextChanged(content); - // }, - // decoration: InputDecoration(labelText: TranslationBase.of(context).enterDocName, fillColor: Colors.white, prefixIcon: Icon(Icons.search), border: OutlineInputBorder())), - // ), inputWidget(TranslationBase.of(context).enterDocName, '', doctorNameController), - ], ), ), diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 50a90f39..eb1c1961 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2571,6 +2571,9 @@ class TranslationBase { String get viewDocList => localizedValues["viewDocList"][locale.languageCode]; String get bodyFatTitle => localizedValues["bodyFatTitle"][locale.languageCode]; + + String get cholesTitle => localizedValues["cholesTitle"][locale.languageCode]; + } class TranslationBaseDelegate extends LocalizationsDelegate { From 4a8fc386263a4124dd244f194df84224aa04d7e1 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Thu, 28 Oct 2021 15:11:52 +0300 Subject: [PATCH 47/60] live care design 2.0 --- lib/config/config.dart | 4 +- lib/pages/livecare/clinic_timings_page.dart | 118 +++++++ .../livecare/live_care_payment_page.dart | 316 ++++++++++++++++++ .../livecare/widgets/LiveCareHistoryCard.dart | 15 +- .../widgets/LiveCarePaymentDialog.dart | 1 + lib/pages/livecare/widgets/clinic_card.dart | 88 ++--- lib/pages/livecare/widgets/clinic_list.dart | 86 +++-- 7 files changed, 542 insertions(+), 86 deletions(-) create mode 100644 lib/pages/livecare/clinic_timings_page.dart create mode 100644 lib/pages/livecare/live_care_payment_page.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 6f05a414..bca5db17 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -15,8 +15,8 @@ const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/livecare/clinic_timings_page.dart b/lib/pages/livecare/clinic_timings_page.dart new file mode 100644 index 00000000..7e92a3c4 --- /dev/null +++ b/lib/pages/livecare/clinic_timings_page.dart @@ -0,0 +1,118 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class ClinicTimingsPage extends StatefulWidget { + final clinicName; + final List patientERGetClinicsServiceTimingsList; + + ClinicTimingsPage({@required this.clinicName, @required this.patientERGetClinicsServiceTimingsList}); + + @override + _LiveCarePatmentPageState createState() => _LiveCarePatmentPageState(); +} + +class _LiveCarePatmentPageState extends State { + ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).clinicSchedule, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + description: TranslationBase.of(context).erConsultation, + body: Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Expanded( + child: ListView.separated( + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(top: index == 0 ? 12 : 0, bottom: (index == widget.patientERGetClinicsServiceTimingsList.length - 1) ? 12 : 0), + child: showItem(widget.patientERGetClinicsServiceTimingsList[index]), + ); + }, + separatorBuilder: (context, index) { + return mHeight(12); + }, + itemCount: widget.patientERGetClinicsServiceTimingsList.length, + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.all(12), + color: Colors.white, + child: DefaultButton( + TranslationBase.of(context).back, + () { + Navigator.pop(context); + }, + ), + ), + ], + ), + ), + ); + } + + Widget showItem(PatientERGetClinicsServiceTimingsList item) { + return Container( + width: double.infinity, + padding: EdgeInsets.only(left: 12, right: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 1, + child: Text( + item.dayOfWeekStr, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.42, + fontWeight: FontWeight.w600, + ), + ), + ), + Expanded( + flex: 3, + child: Container( + width: double.infinity, + decoration: cardRadius(12), + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + for (int i = 0; i < item.shiftTimings.length; i++) + Text( + TranslationBase.of(context).from + " " + item.shiftTimings[i].startTime + " " + TranslationBase.of(context).to + " " + item.shiftTimings[i].endTime, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.42, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/livecare/live_care_payment_page.dart b/lib/pages/livecare/live_care_payment_page.dart new file mode 100644 index 00000000..3980c5a7 --- /dev/null +++ b/lib/pages/livecare/live_care_payment_page.dart @@ -0,0 +1,316 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class LiveCarePatmentPage extends StatefulWidget { + GetERAppointmentFeesList getERAppointmentFeesList; + int waitingTime; + String clinicName; + + LiveCarePatmentPage({@required this.getERAppointmentFeesList, @required this.waitingTime, @required this.clinicName}); + + @override + _LiveCarePatmentPageState createState() => _LiveCarePatmentPageState(); +} + +class _LiveCarePatmentPageState extends State { + int _selected = 0; + + ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double itemHeight = ((size.height - kToolbarHeight - 24) * 0.42) / 2; + final double itemWidth = size.width / 2; + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).livecare, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + description: TranslationBase.of(context).erConsultation, + body: Container( + width: double.infinity, + + height: double.infinity, + child: Column( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + widget.clinicName, + style: TextStyle( + fontSize: 19.0, + fontWeight: FontWeight.bold, + letterSpacing: -1.44, + ), + ), + mHeight(8), + Text( + TranslationBase.of(context).expectedWaiting, + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), + ), + Text( + widget.waitingTime.toString() + " " + TranslationBase.of(context).minute, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: CustomColors.accentColor, + letterSpacing: -0.66, + ), + ), + mHeight(16), + Container( + decoration: cardRadius(12), + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).erConsultFee, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + mHeight(10), + Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).patientShareToDo, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + color: CustomColors.textColor, + fontWeight: FontWeight.w600, + ), + ), + ), + Expanded( + child: Text( + widget.getERAppointmentFeesList.amount + " " + widget.getERAppointmentFeesList.currency, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + mHeight(4), + mDivider(CustomColors.lightGreyColor), + mHeight(4), + Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).patientTaxToDo, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + color: CustomColors.textColor, + fontWeight: FontWeight.w600, + ), + ), + ), + Expanded( + child: Text( + widget.getERAppointmentFeesList.tax + " " + widget.getERAppointmentFeesList.currency, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + mHeight(4), + mDivider(CustomColors.lightGreyColor), + mHeight(4), + Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).patientShareTotalToDo, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + color: CustomColors.textColor, + fontWeight: FontWeight.w600, + ), + ), + ), + Expanded( + child: Text( + widget.getERAppointmentFeesList.total + " " + widget.getERAppointmentFeesList.currency, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ], + ), + ), + mHeight(12), + Container( + padding: EdgeInsets.all(12), + decoration: cardRadius(12), + child: Row( + children: [ + SvgPicture.asset( + "assets/images/new/services/raise_comp.svg", + color: CustomColors.green, + width: 18, + height: 18, + ), + mWidth(10), + Expanded( + child: Text( + TranslationBase.of(context).insuredPatient, + style: TextStyle( + fontSize: 10.0, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Radio( + value: 1, + groupValue: _selected, + onChanged: onRadioChanged, + ), + Text( + TranslationBase.of(context).agreeTo, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.textColor, + ), + ), + mWidth(4), + Text( + TranslationBase.of(context).termsConditoins, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.accentColor, + ), + ), + ], + ), + ), + mFlex(1), + Text( + TranslationBase.of(context).upComingPayOption, + style: new TextStyle( + fontSize: 12.0, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, + ), + ), + Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), + child: getPaymentMethods(), + ), + + + ], + ), + ), + ), + Container( + padding: EdgeInsets.all(12), + color: Colors.white, + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancel, + () { + Navigator.pop(context, false); + }, + ), + ), + mWidth(12), + Expanded( + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (_selected == 0) { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + } else { + Navigator.pop(context, true); + } + }, + color: CustomColors.green, + ), + ), + ], + ), + ), + ], + ), + ), + ); + } + + void onRadioChanged(int value) { + setState(() { + _selected = value; + }); + } + + _getNormalText(text) { + return Container( + margin: EdgeInsets.only(top: 10.0, right: 10.0), + child: Text(text, textAlign: TextAlign.start, style: TextStyle(fontSize: 14, letterSpacing: 0.5, color: Colors.black)), + ); + } + + _getMarginText(text) { + return Container( + margin: EdgeInsets.only(top: 10.0, right: 10.0, bottom: 10.0), + child: Text(text, textAlign: TextAlign.start, style: TextStyle(fontSize: 14, letterSpacing: 0.5, fontWeight: FontWeight.bold, color: Colors.black)), + ); + } +} diff --git a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart index da9ad863..91659278 100644 --- a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart +++ b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart @@ -60,16 +60,16 @@ class _LiveCareHistoryCardState extends State { ], ), child: Container( - margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), + margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 0, right: projectViewModel.isArabic ? 0 : 0), padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.white, width: 1), borderRadius: BorderRadius.only( - bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), - topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), - bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), - topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + bottomRight: projectViewModel.isArabic ? Radius.circular(10) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(10) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(10), + topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(10), ), ), child: Column( @@ -77,12 +77,13 @@ class _LiveCareHistoryCardState extends State { mainAxisSize: MainAxisSize.min, children: [ Text( - widget.erRequestHistoryList.stringCallStatus == "Completed" ? widget.erRequestHistoryList.stringCallStatus : "Pending", + widget.erRequestHistoryList.stringCallStatus , style: TextStyle( fontSize: 10.0, fontWeight: FontWeight.w600, letterSpacing: -0.4, - color: widget.erRequestHistoryList.stringCallStatus == "Completed" ? CustomColors.green : CustomColors.orange, + color: CustomColors.green, + //color: widget.erRequestHistoryList.stringCallStatus == "Completed" ? CustomColors.green : CustomColors.orange, ), ), mHeight(12), diff --git a/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart b/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart index a8950e5d..1e2eaa1b 100644 --- a/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart +++ b/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart @@ -40,6 +40,7 @@ class _LiveCarePaymentDialogState extends State { height: 600.0, margin: EdgeInsets.all(20.0), width: 500.0, + color: Colors.red, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index e788a5cd..0f534d98 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -11,6 +11,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; +import '../clinic_timings_page.dart'; import 'ClinicTimingsDialog.dart'; // ignore: must_be_immutable @@ -124,27 +125,30 @@ class _State extends State { ], ), ), - Container( - padding: EdgeInsets.only(left: 8,right: 8,top: 4,bottom: 4), - decoration: containerRadius(CustomColors.devider, 100), - child: Row( - children: [ - SvgPicture.asset( - "assets/images/new-design/ic_schedule.svg", - width: 16, - height: 16, - color: Colors.black, - ), - mWidth(4), - Text( - TranslationBase.of(context).schedule, - style: TextStyle( - fontSize: 11, - letterSpacing: -0.44, - fontWeight: FontWeight.w600, + InkWell( + onTap: (){ getClinicTimings(widget.patientERGetClinicsList);}, + child: Container( + padding: EdgeInsets.only(left: 8,right: 8,top: 4,bottom: 4), + decoration: containerRadius(CustomColors.devider, 100), + child: Row( + children: [ + SvgPicture.asset( + "assets/images/new-design/ic_schedule.svg", + width: 16, + height: 16, + color: Colors.black, ), - ) - ], + mWidth(4), + Text( + TranslationBase.of(context).schedule, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ) + ], + ), ), ), ], @@ -164,26 +168,30 @@ class _State extends State { clinicsServiceTimingsResponse = ClinicsServiceTimingsResponse.fromJson(res); print(clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList.length); - showGeneralDialog( - barrierColor: Colors.black.withOpacity(0.5), - transitionBuilder: (context, a1, a2, widget) { - final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; - return Transform( - transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), - child: Opacity( - opacity: a1.value, - child: ClinicTimingsDialog( - clinicName: patientERGetClinicsList.serviceName, - patientERGetClinicsServiceTimingsList: clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList, - ), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}); + navigateTo(context, ClinicTimingsPage( + clinicName: patientERGetClinicsList.serviceName, + patientERGetClinicsServiceTimingsList: clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList, + )); + // showGeneralDialog( + // barrierColor: Colors.black.withOpacity(0.5), + // transitionBuilder: (context, a1, a2, widget) { + // final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + // return Transform( + // transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + // child: Opacity( + // opacity: a1.value, + // child: ClinicTimingsDialog( + // clinicName: patientERGetClinicsList.serviceName, + // patientERGetClinicsServiceTimingsList: clinicsServiceTimingsResponse.patientERGetClinicsServiceTimingsList, + // ), + // ), + // ); + // }, + // transitionDuration: Duration(milliseconds: 500), + // barrierDismissible: true, + // barrierLabel: '', + // context: context, + // pageBuilder: (context, animation1, animation2) {}); }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 2127cd57..df3c83cb 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -29,6 +29,8 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../live_care_payment_page.dart'; + class ClinicList extends StatefulWidget { final Function getLiveCareHistory; @@ -174,32 +176,43 @@ class _clinic_listState extends State { } showLiveCarePaymentDialog(GetERAppointmentFeesList getERAppointmentFeesList, int waitingTime) { - showGeneralDialog( - barrierColor: Colors.black.withOpacity(0.5), - transitionBuilder: (context, a1, a2, widget) { - final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; - return Transform( - transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), - child: Opacity( - opacity: a1.value, - child: LiveCarePaymentDialog(getERAppointmentFeesList: getERAppointmentFeesList, waitingTime: waitingTime, clinicName: selectedClinicName), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}) - .then((value) { - if (value) { - if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { - showLiveCareInfoDialog(getERAppointmentFeesList); - } else { - navigateToPaymentMethod(getERAppointmentFeesList, context); + navigateTo(context, LiveCarePatmentPage(getERAppointmentFeesList: getERAppointmentFeesList, waitingTime: waitingTime, clinicName: selectedClinicName)).then( + (value) { + if (value) { + if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { + showLiveCareInfoDialog(getERAppointmentFeesList); + } else { + navigateToPaymentMethod(getERAppointmentFeesList, context); + } } - } - }); + }, + ); + // showGeneralDialog( + // barrierColor: Colors.black.withOpacity(0.5), + // transitionBuilder: (context, a1, a2, widget) { + // final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + // return Transform( + // transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + // child: Opacity( + // opacity: a1.value, + // child: LiveCarePaymentDialog(getERAppointmentFeesList: getERAppointmentFeesList, waitingTime: waitingTime, clinicName: selectedClinicName), + // ), + // ); + // }, + // transitionDuration: Duration(milliseconds: 500), + // barrierDismissible: true, + // barrierLabel: '', + // context: context, + // pageBuilder: (context, animation1, animation2) {}) + // .then((value) { + // if (value) { + // if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { + // showLiveCareInfoDialog(getERAppointmentFeesList); + // } else { + // navigateToPaymentMethod(getERAppointmentFeesList, context); + // } + // } + // }); } showLiveCareInfoDialog(GetERAppointmentFeesList getERAppointmentFeesList) async { @@ -548,7 +561,7 @@ class _clinic_listState extends State { }, ), Container( - height: 50.0, + height: 10.0, ), ], )), @@ -557,17 +570,16 @@ class _clinic_listState extends State { : Container(), isDataLoaded ? Container( - - color: Colors.white, - width: double.infinity, - padding: EdgeInsets.all(16), - child: DefaultButton( - TranslationBase.of(context).start, - () { - startLiveCare(); - }, - ), - ) + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(16), + child: DefaultButton( + TranslationBase.of(context).start, + () { + startLiveCare(); + }, + ), + ) : Container(), ], ); From 853ca033d2fffad6dbea302b0abae2ee9adc10ea Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 28 Oct 2021 16:15:42 +0300 Subject: [PATCH 48/60] LiveCare Schedule API fix --- .../livecare_services/livecare_provider.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/services/livecare_services/livecare_provider.dart b/lib/services/livecare_services/livecare_provider.dart index a71bd5c9..fa40bd57 100644 --- a/lib/services/livecare_services/livecare_provider.dart +++ b/lib/services/livecare_services/livecare_provider.dart @@ -63,15 +63,15 @@ class LiveCareService extends BaseService { var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", + // "LanguageID": languageID == 'ar' ? 1 : 2, + // "IPAdress": "10.20.10.20", + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "generalid": 'Cs2020@2016\$2958', + // "PatientOutSA": 0, + // "TokenID": "", + // "DeviceTypeID": req.DeviceTypeID, + // "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 From 40c63ae53bb9e10aac6846a47848349c5966f012 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 28 Oct 2021 16:55:14 +0300 Subject: [PATCH 49/60] dialog ui changes in wallet & improvements. --- lib/config/localized_values.dart | 3 +- .../dialogs/select_country_ingo_Dialog.dart | 2 + .../select_search_criteria_dialog.dart | 139 -------- .../E-Referral/search_for_referrals_page.dart | 227 ++++-------- .../Blood/dialogs/SelectBloodDialog.dart | 328 ------------------ lib/pages/DrawerPages/family/my-family.dart | 18 +- .../medical/balance/advance_payment_page.dart | 165 ++++----- .../dialogs/SelectBeneficiaryDialog.dart | 204 ----------- .../balance/dialogs/SelectCiteisDialog.dart | 1 + .../balance/dialogs/SelectHospitalDialog.dart | 145 -------- .../dialogs/SelectPatientFamilyDialog.dart | 152 -------- .../dialogs/SelectPatientInfoDialog.dart | 146 -------- .../medical/balance/my_balance_page.dart | 242 +++++++------ .../my_trackers/Weight/AddWeightPage.dart | 20 +- .../blood_pressure/AddBloodPressurePage.dart | 23 -- lib/uitl/translations_delegate_base.dart | 2 + lib/widgets/dialogs/RadioStringDialog.dart | 139 -------- 17 files changed, 323 insertions(+), 1633 deletions(-) delete mode 100644 lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_search_criteria_dialog.dart delete mode 100644 lib/pages/Blood/dialogs/SelectBloodDialog.dart delete mode 100644 lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart delete mode 100644 lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart delete mode 100644 lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart delete mode 100644 lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart delete mode 100644 lib/widgets/dialogs/RadioStringDialog.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 4e085e46..34ef5e4f 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -396,8 +396,9 @@ const Map localizedValues = { "PaymentOnline": {"en": "Service", "ar": "الالكتروني"}, "OnlineCheckIn": {"en": "Online Check-In", "ar": "مدفوعات معلقة"}, "MyBalances": {"en": "My Balances", "ar": "رصيدي"}, + "MyWallet": {"en": "My Wallet", "ar": "محفظتى"}, "BalanceAmount": {"en": "Wallet Amount", "ar": "مبلغ المحفظة"}, - "TotalBalance": {"en": "Total Amount", "ar": "المبلغ الإجمالي"}, + "TotalBalance": {"en": "Total Balance", "ar": "إجمالي الرصيد"}, "CreateAdvancedPayment": {"en": "Recharge Wallet", "ar": "شحن المحفظة"}, "AdvancePayment": {"en": "Advance Payment", "ar": "الدفع مقدما"}, "AdvancePaymentLabel": {"en": "You can create and add an Advanced Payment for your account or other accounts.", "ar": "يمكنك تحويل مبلغ لحسابك لدى المجموعة أو لحساب احد المراجعين"}, diff --git a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart index d58fd29f..8046346f 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart @@ -4,6 +4,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; // ignore: must_be_immutable + +// todo 'sikander' remove this file when usage known class SelectCountryDialog extends StatefulWidget { final Function(dynamic) onValueSelected; dynamic selectedCountry; diff --git a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_search_criteria_dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_search_criteria_dialog.dart deleted file mode 100644 index e970f208..00000000 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_search_criteria_dialog.dart +++ /dev/null @@ -1,139 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -// ignore: must_be_immutable -class SelectSearchCriteriaDialog extends StatefulWidget { - List searchCriteria = [ - SearchCriteriaModel(name: "Identification Number",nameAr:"رقم الهوية",value: 1), - SearchCriteriaModel(name: "Referral Number",nameAr:"رقم الإحالة",value: 2), - ]; - final Function(SearchCriteriaModel) onValueSelected; - SearchCriteriaModel selectedCriteria; - ProjectViewModel projectViewModel; - - SelectSearchCriteriaDialog( - {Key key, this.onValueSelected, this.selectedCriteria, this.projectViewModel}); - - @override - _SelectSearchCriteriaDialogState createState() => _SelectSearchCriteriaDialogState(); -} - -class _SelectSearchCriteriaDialogState extends State { - @override - void initState() { - super.initState(); - widget.selectedCriteria = widget.selectedCriteria ?? widget.searchCriteria[0]; - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Text(TranslationBase.of(context).searchCriteria), - Divider(), - ...List.generate( - widget.searchCriteria.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedCriteria = widget.searchCriteria[index]; - }); - }, - child: ListTile( - title: Text(widget.projectViewModel.isArabic ? widget.searchCriteria[index].nameAr : widget.searchCriteria[index].name), - leading: Radio( - value: widget.searchCriteria[index], - groupValue: widget.selectedCriteria, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - widget.selectedCriteria = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Texts( - TranslationBase.of(context).cancel.toUpperCase(), - color: Colors.red, - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(widget.selectedCriteria); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), - ), - ), - ), - ], - ) - ], - ) - ], - ); - } -} - - - - diff --git a/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart index b3fffa4b..5751dcfe 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart @@ -4,17 +4,17 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/ import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/referral_details.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; -import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -23,7 +23,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'dialogs/select_country_ingo_Dialog.dart'; -import 'dialogs/select_search_criteria_dialog.dart'; class SearchForReferralsPage extends StatefulWidget { SearchForReferralsPage({Key key}); @@ -79,74 +78,31 @@ class _SearchForReferralsPageState extends State { SizedBox( height: 10, ), - // InkWell( - // onTap: () => selectSearchCriteriaDialog(), - // child: Container( - // padding: EdgeInsets.all(12), - // width: double.infinity, - // height: 65, - // decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [Texts(getSearchCriteriaName()), Icon(Icons.arrow_drop_down)], - // ), - // ), - // ), - Container( - padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Colors.white, - border: Border.all( - color: Color(0xffefefef), - width: 1, - ), - ), - child: InkWell( - onTap: () => selectSearchCriteriaDialog(projectViewModel), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).selectSearchCriteria, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.44, - ), - ), - Text( - getSearchCriteriaName(projectViewModel), - style: TextStyle( - fontSize: 14, - height: 21 / 14, - fontWeight: FontWeight.w400, - color: Color(0xff2B353E), - letterSpacing: -0.44, - ), - ), - ], - ), - ), - Icon(Icons.arrow_drop_down), - ], + CommonDropDownView(TranslationBase.of(context).selectSearchCriteria, getSearchCriteriaName(projectViewModel), () { + List searchCriteria = [ + SearchCriteriaModel(name: "Identification Number", nameAr: "رقم الهوية", value: 1), + SearchCriteriaModel(name: "Referral Number", nameAr: "رقم الإحالة", value: 2), + ]; + List list = []; + for (int i = 0; i < searchCriteria.length; i++) { + list.add(RadioSelectionDialogModel(projectViewModel.isArabic ? searchCriteria[i].nameAr : searchCriteria[i].name, searchCriteria[i].value)); + } + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: selectedCriteria.value, + onValueSelected: (index) { + selectedCriteria = searchCriteria[index - 1]; + setState(() {}); + }, ), - ), - ), - SizedBox( - height: 12, - ), - - inputWidget(selectedCriteria.value == 1 ? TranslationBase.of(context).enterIdentificationNumber : TranslationBase.of(context).referralNumber, "", _searchTextController, isInputTypeNum: true), - - SizedBox( - height: 12, - ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + inputWidget(selectedCriteria.value == 1 ? TranslationBase.of(context).enterIdentificationNumber : TranslationBase.of(context).referralNumber, "", _searchTextController, + isInputTypeNum: true), + SizedBox(height: 12), PhoneNumberSelectorWidget(onNumberChange: (value) { setState(() { mobileNo = value; @@ -179,9 +135,7 @@ class _SearchForReferralsPageState extends State { // }, // code: _selectedCountry == null ? "11" : _selectedCountry["code"], // ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), if ((model.state == ViewState.Idle && model.allReferral.length == 0)) Center(child: Text(TranslationBase.of(context).noSearchResult)), if ((model.state == ViewState.ErrorLocal)) AppEmbeddedError(error: model.error), model.allReferral.length > 0 @@ -293,92 +247,65 @@ class _SearchForReferralsPageState extends State { return "Country"; } - void selectSearchCriteriaDialog(ProjectViewModel projectViewModel) { - showDialog( - context: context, - child: SelectSearchCriteriaDialog( - selectedCriteria: selectedCriteria, - projectViewModel: projectViewModel, - onValueSelected: (value) { - setState(() { - selectedCriteria = value; - }); - }, - ), - ); - } - Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {VoidCallback suffixTap, bool isEnable = true, bool hasSelection = false, int lines, bool isInputTypeNum = false}) { - return Container( - padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Colors.white, - border: Border.all( - color: Color(0xffefefef), - width: 1, - ), - ), - child: InkWell( - onTap: hasSelection ? () {} : null, - child: Row( - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _labelText, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.44, - ), + return InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text, + controller: _controller, + maxLines: lines, + onChanged: (value) => {setState(() {})}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, ), - TextField( - enabled: isEnable, - scrollPadding: EdgeInsets.zero, - keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text, - controller: _controller, - maxLines: lines, - onChanged: (value) => {setState(() {})}, - style: TextStyle( + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w400, - color: Color(0xff2B353E), - letterSpacing: -0.44, - ), - decoration: InputDecoration( - isDense: true, - hintText: _hintText, - hintStyle: TextStyle( - fontSize: 14, - height: 21 / 14, - fontWeight: FontWeight.w400, - color: Color(0xff575757), - letterSpacing: -0.56, - ), - suffixIconConstraints: BoxConstraints(minWidth: 50), - suffixIcon: suffixTap == null ? null : IconButton(icon: Icon(Icons.mic, color: Color(0xff2E303A)), onPressed: suffixTap), - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, + color: Color(0xff575757), + letterSpacing: -0.56, ), + suffixIconConstraints: BoxConstraints(minWidth: 50), + suffixIcon: suffixTap == null ? null : IconButton(icon: Icon(Icons.mic, color: Color(0xff2E303A)), onPressed: suffixTap), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), - ], - ), + ), + ], ), - if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), - ], - ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], ), - ); + ).withBorderedContainer; } String getSearchCriteriaName(ProjectViewModel projectViewModel) { diff --git a/lib/pages/Blood/dialogs/SelectBloodDialog.dart b/lib/pages/Blood/dialogs/SelectBloodDialog.dart deleted file mode 100644 index 23e9e753..00000000 --- a/lib/pages/Blood/dialogs/SelectBloodDialog.dart +++ /dev/null @@ -1,328 +0,0 @@ -import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - - -class SelectBloodDialog extends StatefulWidget { - - final Blood bloodType; - final Function(Blood) onValueSelected; - - SelectBloodDialog({Key key, this.bloodType, this.onValueSelected}); - - - - @override - _SelectBloodDialogState createState() => _SelectBloodDialogState(this.bloodType); -} - -class _SelectBloodDialogState extends State { - _SelectBloodDialogState(this.bloodType); - Blood bloodType; - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Container( - child: Column( - children: [ - Divider(), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Oplus; - }); - }, - child: ListTile( - title: Text("O+"), - leading: Radio( - value: Blood.Oplus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Ominus; - }); - }, - child: ListTile( - title: Text("O-"), - leading: Radio( - value: Blood.Ominus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.ABminus; - }); - }, - child: ListTile( - title: Text("AB-"), - leading: Radio( - value: Blood.ABminus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.ABplus; - }); - }, - child: ListTile( - title: Text("AB+"), - leading: Radio( - value: Blood.ABplus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Aplus; - }); - }, - child: ListTile( - title: Text("A+"), - leading: Radio( - value: Blood.Aplus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Aminus; - }); - }, - child: ListTile( - title: Text("A-"), - leading: Radio( - value: Blood.Aminus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Bplus; - }); - }, - child: ListTile( - title: Text("B+"), - leading: Radio( - value: Blood.Bplus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - bloodType = Blood.Bminus; - }); - }, - child: ListTile( - title: Text("B-"), - leading: Radio( - value: Blood.Bminus, - groupValue: bloodType, - activeColor: Colors.red[800], - onChanged: (Blood value) { - setState(() { - bloodType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Texts( - TranslationBase.of(context).cancel.toUpperCase(), - color: Colors.red, - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(bloodType); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - ), - ), - ), - ), - ), - ], - ) - ], - ), - ) - ], - ); - } -} diff --git a/lib/pages/DrawerPages/family/my-family.dart b/lib/pages/DrawerPages/family/my-family.dart index 18450954..1d2b470b 100644 --- a/lib/pages/DrawerPages/family/my-family.dart +++ b/lib/pages/DrawerPages/family/my-family.dart @@ -26,6 +26,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -666,14 +667,15 @@ class _MyFamily extends State with TickerProviderStateMixin { } deleteFamily(family, context) { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: TranslationBase.of(context).removeFamilyMember, - okText: TranslationBase.of(context).confirm, - cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => {ConfirmDialog.closeAlertDialog(context), removeFamily(family, context)}, - cancelFunction: () => {}); - dialog.showAlertDialog(context); + showDialog( + context: context, + child: ConfirmWithMessageDialog( + message: TranslationBase.of(context).removeFamilyMember, + onTap: () { + removeFamily(family, context); + }, + ), + ); } removeFamily(GetAllSharedRecordsByStatusList family, context) { diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index 338aff23..6ade52bd 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -8,7 +8,6 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectHospitalDialog.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -16,7 +15,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -24,9 +23,6 @@ import 'package:flutter/material.dart'; import '../../../core/model/my_balance/AdvanceModel.dart'; import 'confirm_payment_page.dart'; -import 'dialogs/SelectBeneficiaryDialog.dart'; -import 'dialogs/SelectPatientFamilyDialog.dart'; -import 'dialogs/SelectPatientInfoDialog.dart'; import 'new_text_Field.dart'; enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } @@ -87,16 +83,48 @@ class _AdvancePaymentPageState extends State { Text( TranslationBase.of(context).advancePaymentLabel, style: TextStyle( - fontSize: 14, + fontSize: 16, fontWeight: FontWeight.w600, - letterSpacing: -0.46, + letterSpacing: -0.64, ), ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), InkWell( - onTap: () => confirmSelectBeneficiaryDialog(model), + onTap: () { + List list = [ + RadioSelectionDialogModel(TranslationBase.of(context).myAccount, 0), + RadioSelectionDialogModel(TranslationBase.of(context).myFamilyFiles, 1), + RadioSelectionDialogModel(TranslationBase.of(context).otherAccount, 2), + ]; + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: + beneficiaryType == BeneficiaryType.MyAccount ? 0 : (beneficiaryType == BeneficiaryType.MyFamilyFiles ? 1 : (beneficiaryType == BeneficiaryType.OtherAccount ? 2 : -1)), + onValueSelected: (index) { + var type; + if (index == 0) { + type = BeneficiaryType.MyAccount; + } else if (index == 1) { + type = BeneficiaryType.MyFamilyFiles; + } else { + type = BeneficiaryType.OtherAccount; + } + + setState(() { + if (type == BeneficiaryType.MyAccount) { + _fileTextController.text = model.user.patientID.toString(); + advanceModel.depositorName = model.user.firstName + " " + model.user.lastName; + } else + _fileTextController.text = ""; + + beneficiaryType = type; + }); + }, + ), + ); + }, child: Container( padding: EdgeInsets.all(8), width: double.infinity, @@ -118,10 +146,7 @@ class _AdvancePaymentPageState extends State { ), ), ), - if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - SizedBox( - height: 12, - ), + if (beneficiaryType == BeneficiaryType.MyFamilyFiles) SizedBox(height: 12), if (beneficiaryType == BeneficiaryType.MyFamilyFiles) InkWell( onTap: () { @@ -152,18 +177,13 @@ class _AdvancePaymentPageState extends State { ), ), ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), NewTextFields( hintText: TranslationBase.of(context).fileNumber, controller: _fileTextController, readOnly: beneficiaryType == BeneficiaryType.OtherAccount ? false : true, ), - if (beneficiaryType == BeneficiaryType.OtherAccount) - SizedBox( - height: 12, - ), + if (beneficiaryType == BeneficiaryType.OtherAccount) SizedBox(height: 12), if (beneficiaryType == BeneficiaryType.OtherAccount) InkWell( onTap: () { @@ -197,9 +217,7 @@ class _AdvancePaymentPageState extends State { ), ), ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), InkWell( onTap: () => confirmSelectHospitalDialog(model.hospitals), child: Container( @@ -223,9 +241,7 @@ class _AdvancePaymentPageState extends State { ), ), ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), NewTextFields( hintText: TranslationBase.of(context).amount, keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), @@ -235,9 +251,7 @@ class _AdvancePaymentPageState extends State { }); }, ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), if (model.user != null) NewTextFields( hintText: TranslationBase.of(context).depositorEmail, @@ -246,9 +260,7 @@ class _AdvancePaymentPageState extends State { email = value; }, ), - SizedBox( - height: 12, - ), + SizedBox(height: 12), NewTextFields( hintText: TranslationBase.of(context).notes, controller: _notesTextController, @@ -334,73 +346,70 @@ class _AdvancePaymentPageState extends State { ); } - void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { - showDialog( - context: context, - child: SelectBeneficiaryDialog( - beneficiaryType: beneficiaryType, - onValueSelected: (value) { - setState(() { - if (value == BeneficiaryType.MyAccount) { - _fileTextController.text = model.user.patientID.toString(); - advanceModel.depositorName = model.user.firstName + " " + model.user.lastName; - } else - _fileTextController.text = ""; - - beneficiaryType = value; - }); - }, - ), - ); - } + int _selectedHospitalIndex = -1; void confirmSelectHospitalDialog(List hospitals) { + List list = [ + for (int i = 0; i < hospitals.length; i++) RadioSelectionDialogModel(hospitals[i].name + ' ${hospitals[i].distanceInKilometers} ' + TranslationBase.of(context).km, i), + ]; showDialog( context: context, - child: SelectHospitalDialog( - hospitals: hospitals, - selectedHospital: _selectedHospital, - onValueSelected: (value) { - setState(() { - _selectedHospital = value; - }); + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = hospitals[index]; + setState(() {}); }, ), ); } + int _selectedPatientIndex = -1; + void confirmSelectPatientDialog(List patientInfoList) { + List list = [ + for (int i = 0; i < patientInfoList.length; i++) RadioSelectionDialogModel(patientInfoList[i].fullName, i), + ]; showDialog( context: context, - child: SelectPatientInfoDialog( - patientInfoList: patientInfoList, - selectedPatientInfo: _selectedPatientInfo, - onValueSelected: (value) { - setState(() { - advanceModel.depositorName = value.fullName; - _selectedPatientInfo = value; - }); + child: RadioSelectionDialog( + listData: list, + isScrollable: true, + selectedIndex: _selectedPatientIndex, + onValueSelected: (index) { + _selectedPatientIndex = index; + _selectedPatientInfo = patientInfoList[index]; + advanceModel.depositorName = _selectedPatientInfo.fullName; + setState(() {}); }, ), ); } + int _selectedFamilyMemberIndex = -1; + void confirmSelectFamilyDialog(List getAllSharedRecordsByStatusList) { - if (getAllSharedRecordsByStatusList.isNotEmpty) + if (getAllSharedRecordsByStatusList.isNotEmpty) { + List list = [ + for (int i = 0; i < getAllSharedRecordsByStatusList.length; i++) RadioSelectionDialogModel(getAllSharedRecordsByStatusList[i].patientName, i), + ]; showDialog( context: context, - child: SelectPatientFamilyDialog( - getAllSharedRecordsByStatusList: getAllSharedRecordsByStatusList, - selectedPatientFamily: selectedPatientFamily, - onValueSelected: (value) { - setState(() { - selectedPatientFamily = value; - _fileTextController.text = selectedPatientFamily.responseID.toString(); - advanceModel.depositorName = value.patientName; - }); + child: RadioSelectionDialog( + listData: list, + isScrollable: true, + selectedIndex: _selectedFamilyMemberIndex, + onValueSelected: (index) { + _selectedFamilyMemberIndex = index; + selectedPatientFamily = getAllSharedRecordsByStatusList[index]; + setState(() {}); }, ), ); + } } String getBeneficiaryType() { diff --git a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart b/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart deleted file mode 100644 index 526ffaf6..00000000 --- a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart +++ /dev/null @@ -1,204 +0,0 @@ -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../../../Constants.dart'; -import '../advance_payment_page.dart'; - -class SelectBeneficiaryDialog extends StatefulWidget { - final BeneficiaryType beneficiaryType; - final Function(BeneficiaryType) onValueSelected; - - SelectBeneficiaryDialog({Key key, this.beneficiaryType, this.onValueSelected}); - - @override - _SelectBeneficiaryDialogState createState() => _SelectBeneficiaryDialogState(this.beneficiaryType); -} - -class _SelectBeneficiaryDialogState extends State { - _SelectBeneficiaryDialogState(this.beneficiaryType); - - BeneficiaryType beneficiaryType; - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Container( - child: Column( - children: [ - Divider(), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - beneficiaryType = BeneficiaryType.MyAccount; - }); - }, - child: ListTile( - title: Text( - TranslationBase.of(context).myAccount, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: BeneficiaryType.MyAccount, - groupValue: beneficiaryType, - activeColor: secondaryColor, - onChanged: (BeneficiaryType value) { - setState(() { - beneficiaryType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - beneficiaryType = BeneficiaryType.MyFamilyFiles; - }); - }, - child: ListTile( - title: Text( - TranslationBase.of(context).myFamilyFiles, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: BeneficiaryType.MyFamilyFiles, - groupValue: beneficiaryType, - activeColor: Color(0xffC5272D), - onChanged: (BeneficiaryType value) { - setState(() { - beneficiaryType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - beneficiaryType = BeneficiaryType.OtherAccount; - }); - }, - child: ListTile( - title: Text( - TranslationBase.of(context).otherAccount, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: BeneficiaryType.OtherAccount, - groupValue: beneficiaryType, - activeColor: Color(0xffC5272D), - onChanged: (BeneficiaryType value) { - setState(() { - beneficiaryType = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Text( - TranslationBase.of(context).cancel.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - color: Color(0xffC5272D), - ), - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(beneficiaryType); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Text( - TranslationBase.of(context).ok.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - ), - ), - ), - ), - ], - ) - ], - ), - ) - ], - ); - } -} diff --git a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart index 19e4fea4..d0f991ac 100644 --- a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart @@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +// todo 'sikander' remove this file when usage known class SelectCiteisDialog extends StatefulWidget { final List hospitals; final Function(CitiesModel) onValueSelected; diff --git a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart b/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart deleted file mode 100644 index fd47ea1b..00000000 --- a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart +++ /dev/null @@ -1,145 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../../../Constants.dart'; - -class SelectHospitalDialog extends StatefulWidget { - final List hospitals; - final Function(HospitalsModel) onValueSelected; - HospitalsModel selectedHospital; - - SelectHospitalDialog({Key key, this.hospitals, this.onValueSelected, this.selectedHospital}); - - @override - _SelectHospitalDialogState createState() => _SelectHospitalDialogState(); -} - -class _SelectHospitalDialogState extends State { - @override - void initState() { - super.initState(); - widget.selectedHospital = widget.selectedHospital ?? widget.hospitals[0]; - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Divider(), - ...List.generate( - widget.hospitals.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedHospital = widget.hospitals[index]; - }); - }, - child: ListTile( - title: Text( - widget.hospitals[index].name + ' ${widget.hospitals[index].distanceInKilometers} ' + TranslationBase.of(context).km, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: widget.hospitals[index], - groupValue: widget.selectedHospital, - activeColor: secondaryColor, - onChanged: (value) { - setState(() { - widget.selectedHospital = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Text( - TranslationBase.of(context).cancel.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - color: Colors.red - ), - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(widget.selectedHospital); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Text( - TranslationBase.of(context).ok, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - ), - ), - ), - ), - ], - ) - ], - ) - ], - ); - } -} diff --git a/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart deleted file mode 100644 index d4b2e8fb..00000000 --- a/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../../../Constants.dart'; - -class SelectPatientFamilyDialog extends StatefulWidget { - final List getAllSharedRecordsByStatusList; - final Function(GetAllSharedRecordsByStatusList) onValueSelected; - GetAllSharedRecordsByStatusList selectedPatientFamily; - - List getAllSharedRecordsByStatusApprovedList = new List(); - - SelectPatientFamilyDialog({Key key, this.getAllSharedRecordsByStatusList, this.onValueSelected, this.selectedPatientFamily}); - - @override - _SelectPatientFamilyDialogState createState() => _SelectPatientFamilyDialogState(); -} - -class _SelectPatientFamilyDialogState extends State { - @override - void initState() { - super.initState(); - widget.selectedPatientFamily = widget.selectedPatientFamily ?? widget.getAllSharedRecordsByStatusList[0]; - - if (widget.getAllSharedRecordsByStatusList.isNotEmpty) - widget.getAllSharedRecordsByStatusList.forEach((element) { - if (element.status == 3) widget.getAllSharedRecordsByStatusApprovedList.add(element); - }); - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Divider(), - ...List.generate( - widget.getAllSharedRecordsByStatusApprovedList.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedPatientFamily = widget.getAllSharedRecordsByStatusApprovedList[index]; - }); - }, - child: ListTile( - title: Text( - widget.getAllSharedRecordsByStatusApprovedList[index].patientName, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: widget.getAllSharedRecordsByStatusApprovedList[index], - groupValue: widget.selectedPatientFamily, - activeColor: secondaryColor, - onChanged: (value) { - setState(() { - widget.selectedPatientFamily = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Text( - TranslationBase.of(context).cancel.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - color: Colors.red, - ), - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(widget.selectedPatientFamily); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Text( - TranslationBase.of(context).ok, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - ), - ), - ), - ), - ], - ) - ], - ) - ], - ); - } -} diff --git a/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart deleted file mode 100644 index 759a6874..00000000 --- a/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart +++ /dev/null @@ -1,146 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../../../Constants.dart'; - -class SelectPatientInfoDialog extends StatefulWidget { - final List patientInfoList; - - final Function(PatientInfo) onValueSelected; - PatientInfo selectedPatientInfo; - - SelectPatientInfoDialog({Key key, this.patientInfoList, this.onValueSelected, this.selectedPatientInfo}); - - @override - _SelectPatientInfoDialogState createState() => _SelectPatientInfoDialogState(); -} - -class _SelectPatientInfoDialogState extends State { - @override - void initState() { - super.initState(); - widget.selectedPatientInfo = widget.selectedPatientInfo ?? widget.patientInfoList[0]; - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Divider(), - ...List.generate( - widget.patientInfoList.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedPatientInfo = widget.patientInfoList[index]; - }); - }, - child: ListTile( - title: Text( - widget.patientInfoList[index].fullName, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - leading: Radio( - value: widget.patientInfoList[index], - groupValue: widget.selectedPatientInfo, - activeColor: secondaryColor, - onChanged: (value) { - setState(() { - widget.selectedPatientInfo = value; - }); - }, - ), - ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Text( - TranslationBase.of(context).cancel.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - color: Colors.red, - ), - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(widget.selectedPatientInfo); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Text( - TranslationBase.of(context).ok.toUpperCase(), - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - ), - ), - ), - ), - ], - ) - ], - ) - ], - ); - } -} diff --git a/lib/pages/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index 8c98ebc8..640b18f9 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -1,14 +1,16 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/my_balance/patient_advance_balance_amount.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; import 'advance_payment_page.dart'; @@ -24,118 +26,156 @@ class MyBalancePage extends StatelessWidget { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBarTitle: TranslationBase.of(context).myBalances, + appBarTitle: TranslationBase.of(context).myWallet, imagesInfo: imagesInfo, description: TranslationBase.of(context).infoMyBalance, showNewAppBar: true, showNewAppBarTitle: true, backgroundColor: CustomColors.appBackgroudGreyColor, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).balanceAmount, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - ), - ), - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(8), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - color: Colors.red[700], - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(7), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '${model.totalAdvanceBalanceAmount ?? 0} ' + TranslationBase.of(context).sar, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, - color: Colors.white, - ), - ), - Text( - TranslationBase.of(context).totalBalance, - style: TextStyle( - fontSize: 14, - letterSpacing: -0.46, - color: Colors.white, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.fromLTRB(14, 12, 10, 12), + decoration: BoxDecoration( + color: Color(0xff2B353E), + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), ), - ], - ), - ), - SizedBox( - height: 9, - ), - ...List.generate( - model.patientAdvanceBalanceAmountList.length, - (index) => Container( - padding: EdgeInsets.all(8), - height: 65, - margin: EdgeInsets.only(top: 8), - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '${model.patientAdvanceBalanceAmountList[index].patientAdvanceBalanceAmount} ' + TranslationBase.of(context).sar, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - letterSpacing: -0.46, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + "assets/images/new/services/balance_credit.svg", + height: 40, + width: 40, + color: Colors.white, + ), + SizedBox(height: 6), + Text( + TranslationBase.of(context).totalBalance, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.96, + fontWeight: FontWeight.bold, + color: Colors.white, + //height: 16/22 + ), + ), + ], + ), ), - ), - Text( - model.patientAdvanceBalanceAmountList[index].projectDescription, - style: TextStyle( - fontSize: 14, - letterSpacing: -0.46, + Container( + padding: EdgeInsets.fromLTRB(14, 10, 12, 10), + decoration: BoxDecoration( + color: Color(0xff3f4850), + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + double.parse(model.totalAdvanceBalanceAmount?.toString() ?? "0").toStringAsFixed(2), + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + letterSpacing: -3.2, + height: 40 / 35, + color: Colors.white, + ), + ), + Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.96, + color: Colors.white, + ), + ), + ], + ), ), - ), - ], + ], + ), ), - ), + SizedBox(height: 12), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (cxt, index) { + PatientAdvanceBalanceAmount balanceAmount = model.patientAdvanceBalanceAmountList[index]; + double amount = double.parse(balanceAmount.patientAdvanceBalanceAmount?.toString() ?? "0"); + return Container( + padding: EdgeInsets.fromLTRB(14, 18, 14, 18), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + balanceAmount.projectDescription, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: amount > 0 ? FontWeight.bold : FontWeight.w500, + color: Color(0xff2E303A), + ), + ), + ), + Text( + amount.toStringAsFixed(2) + " " + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: amount > 0 ? FontWeight.bold : FontWeight.w500, + color: Color(0xff2E303A), + ), + ), + ], + ), + ); + }, + separatorBuilder: (cxt, index) => SizedBox(height: 12), + itemCount: model.patientAdvanceBalanceAmountList.length), + ], ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.13, - ) - ], + ), ), - ), - ), - bottomSheet: Container( - // height: MediaQuery.of(context).size.height * 0.12, - height: 70.0, - color: Colors.white, - width: double.infinity, - padding: EdgeInsets.all(12), - child: DefaultButton( - // textColor: Colors.white, - // color: CustomColors.accentColor, - TranslationBase.of(context).createAdvancedPayment, - () { - Navigator.push(context, FadePage(page: AdvancePaymentPage())); - }, - ), + DefaultButton( + TranslationBase.of(context).createAdvancedPayment, + () { + Navigator.push(context, FadePage(page: AdvancePaymentPage())); + }, + ).insideContainer, + ], ), ), ); diff --git a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart index 9eb3e1a5..5ef8c69c 100644 --- a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart +++ b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart @@ -9,7 +9,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; + import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -280,24 +280,6 @@ class _AddWeightPageState extends State { return " ${timeWeightDate.hour}:${timeWeightDate.minute}"; } - void confirmSelectMeasureTimeDialog(List list) { - showDialog( - context: context, - child: RadioStringDialog( - radioList: list, - title: TranslationBase.of(context).measureUnit, - selectedValue: measureTimeSelectedType, - onValueSelected: (value) { - setState(() { - measureTimeSelectedType = value; - weightUnit = list.indexOf(value); - validateForm(); - }); - }, - ), - ); - } - void validateForm() { if (_weightValueController.text.length > 0 && measureTimeSelectedType != null) { setState(() { diff --git a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart index 77bb45b7..a4c0b943 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart @@ -6,10 +6,8 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -119,9 +117,6 @@ class _AddBloodPressurePageState extends State { }, ), ); - return; - - confirmSelectMeasureTimeDialog(projectViewModel.isArabic ? measureTimeArList : measureTimeEnList); }, child: Container( padding: EdgeInsets.all(12), @@ -277,24 +272,6 @@ class _AddBloodPressurePageState extends State { return " ${timeSugarDate.hour}:${timeSugarDate.minute}"; } - void confirmSelectMeasureTimeDialog(List list) { - showDialog( - context: context, - child: RadioStringDialog( - radioList: list, - title: TranslationBase.of(context).selectArm, - selectedValue: measureTimeSelectedType, - onValueSelected: (value) { - setState(() { - measureTimeSelectedType = value; - measuredArm = list.indexOf(value); - validateForm(); - }); - }, - ), - ); - } - void validateForm() { print("_bloodSystolicValueController " + _bloodSystolicValueController.text.length.toString()); if (_bloodSystolicValueController.text.length > 0 && _bloodDiastolicValueController.text.length > 0) { diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 396afd00..89773321 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -795,6 +795,8 @@ class TranslationBase { String get myBalances => localizedValues['MyBalances'][locale.languageCode]; + String get myWallet => localizedValues['MyWallet'][locale.languageCode]; + String get balanceAmount => localizedValues['BalanceAmount'][locale.languageCode]; String get totalBalance => localizedValues['TotalBalance'][locale.languageCode]; diff --git a/lib/widgets/dialogs/RadioStringDialog.dart b/lib/widgets/dialogs/RadioStringDialog.dart deleted file mode 100644 index 49a16142..00000000 --- a/lib/widgets/dialogs/RadioStringDialog.dart +++ /dev/null @@ -1,139 +0,0 @@ -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class RadioStringDialog extends StatefulWidget { - final List radioList; - final Function(String) onValueSelected; - final String title; - String selectedValue; - - RadioStringDialog({Key key, this.radioList, this.onValueSelected, this.selectedValue, this.title}); - - @override - _RadioStringDialogState createState() => _RadioStringDialogState(); -} - -class _RadioStringDialogState extends State { - @override - void initState() { - super.initState(); - widget.selectedValue = widget.selectedValue ?? widget.radioList[0]; - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - title: Container( - width: double.infinity, - child: Center( - child: Texts( - widget.title, - textAlign: TextAlign.center, - ))), - children: [ - Container( - height: widget.radioList.length > 3 ? MediaQuery.of(context).size.height * 0.6 : null, - child: SingleChildScrollView( - child: Column( - children: [ - Divider(), - ...List.generate( - widget.radioList.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // SizedBox( - // height: 2, - // ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedValue = widget.radioList[index]; - }); - }, - child: ListTile( - title: Texts( - widget.radioList[index], - fontSize: 14, - ), - leading: Radio( - value: widget.radioList[index], - groupValue: widget.selectedValue, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - widget.selectedValue = value; - }); - }, - ), - ), - ), - ) - ], - ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - ], - ), - ), - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Texts( - TranslationBase.of(context).cancel.toUpperCase(), - color: Colors.red, - ), - ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onValueSelected(widget.selectedValue); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - ), - ), - ), - ), - ), - ], - ) - ], - ); - } -} From 6af1747f121b067e07db5dbdc211127b4dbfe5f5 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Thu, 28 Oct 2021 16:56:47 +0300 Subject: [PATCH 50/60] live care design 3.0 --- lib/config/config.dart | 4 +- .../schedule_clinic_card.dart | 79 ++++++++++--- lib/pages/livecare/widgets/clinic_list.dart | 110 +++++++++--------- 3 files changed, 118 insertions(+), 75 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index bca5db17..6f05a414 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -15,8 +15,8 @@ const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart index 72ca4ce9..330fec35 100644 --- a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart +++ b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart @@ -1,15 +1,15 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareScheduleClinicsListResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class ScheduleClinicCard extends StatefulWidget { bool isSelected; final ClinicsHaveScheduleList clinicsHaveScheduleList; var languageID; - ScheduleClinicCard( - {this.isSelected, - this.languageID, - @required this.clinicsHaveScheduleList}); + ScheduleClinicCard({this.isSelected, this.languageID, @required this.clinicsHaveScheduleList}); @override _ScheduleClinicCardState createState() => _ScheduleClinicCardState(); @@ -18,29 +18,72 @@ class ScheduleClinicCard extends StatefulWidget { class _ScheduleClinicCardState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return Container( - child: Card( - margin: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 8.0), - color: widget.isSelected ? Color(0xff06b806) : Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + width: double.infinity, + margin: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 8.0), + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(width: widget.isSelected ? 3 : 0, color: widget.isSelected ? CustomColors.green : Colors.transparent), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.transparent, + ), + child: Container( + decoration: BoxDecoration( + color: CustomColors.green , + borderRadius: BorderRadius.all( + Radius.circular(6.0), + ), ), child: Container( - width: MediaQuery.of(context).size.width * 0.8, - padding: EdgeInsets.all(12.0), + margin: EdgeInsets.only( + left: projectViewModel.isArabic + ? 0 + : widget.isSelected + ? 4 + : 6, + right: projectViewModel.isArabic ? widget.isSelected + ? 4 + : 6: 0), + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.only( + bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), + ), + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Container( child: Text( - widget.languageID == 'ar' - ? widget.clinicsHaveScheduleList.clinicDescN != null ? widget.clinicsHaveScheduleList.clinicDescN: "" - : widget.clinicsHaveScheduleList.clinicDesc != null ? widget.clinicsHaveScheduleList.clinicDesc: "Test Clinic", - style: TextStyle( - fontSize: 16.0, - color: - widget.isSelected ? Colors.white : Colors.black)), + widget.languageID == 'ar' + ? widget.clinicsHaveScheduleList.clinicDescN != null + ? widget.clinicsHaveScheduleList.clinicDescN + : "" + : widget.clinicsHaveScheduleList.clinicDesc != null + ? widget.clinicsHaveScheduleList.clinicDesc + : "Test Clinic", + style: TextStyle( + fontSize: 16.0, + color: Colors.black, + fontWeight: FontWeight.w600, + ), + ), ), ], ), diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index df3c83cb..988d102c 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -16,6 +16,7 @@ import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_card.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; @@ -450,64 +451,63 @@ class _clinic_listState extends State { return Column( children: [ isDataLoaded - ? Container( - height: MediaQuery.of(context).size.height * 0.7, - child: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length > 0 - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - updateSelectedScheduleIndex(liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index]); - }, - child: ScheduleClinicCard( - isSelected: selectedClinicID == liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index].serviceID ? true : false, - clinicsHaveScheduleList: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index], - languageID: languageID, - ), - ); - }, - ), - Container( - height: 10.0, - ), - ], - ) - : getNoDataWidget(context), - ) + ? Expanded( + child: Container( + child: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length > 0 + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(10), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + updateSelectedScheduleIndex(liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index]); + }, + child: ScheduleClinicCard( + isSelected: selectedClinicID == liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index].serviceID ? true : false, + clinicsHaveScheduleList: liveCareScheduleClinicsListResponse.clinicsHaveScheduleList[index], + languageID: languageID, + ), + ); + }, + ), + Container( + height: 10.0, + ), + ], + ) + : getNoDataWidget(context), + ), + ) : Container(), isDataLoaded - ? Align( - alignment: FractionalOffset.bottomCenter, - child: Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.7, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - elevation: 0, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: startScheduleLiveCare, - child: Text(TranslationBase.of(context).start, style: TextStyle(fontSize: 18.0)), - ), - ), + ? Container( + width: double.infinity, + color: Colors.white, + padding: EdgeInsets.all(12), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), ), - ) + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: CustomColors.accentColor, + textColor: Colors.white, + elevation: 0, + disabledTextColor: Colors.white, + disabledColor: new Color(0xFFbcc2c4), + onPressed: startScheduleLiveCare, + child: Text(TranslationBase.of(context).start, style: TextStyle(fontSize: 18.0)), + ), + ), + ) : Container(), ], ); From d2223da3c23242e7a8bd3b003bd4745ebb21cf93 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 28 Oct 2021 17:00:57 +0300 Subject: [PATCH 51/60] improvements. --- lib/pages/medical/balance/my_balance_page.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index 640b18f9..e4ff9581 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -92,10 +92,10 @@ class MyBalancePage extends StatelessWidget { Text( double.parse(model.totalAdvanceBalanceAmount?.toString() ?? "0").toStringAsFixed(2), style: TextStyle( - fontSize: 28, + fontSize: 24, fontWeight: FontWeight.bold, - letterSpacing: -3.2, - height: 40 / 35, + letterSpacing: -1.44, + height: 24 / 23, color: Colors.white, ), ), From 57ea450662fa3d8e259e0f2bcc18f621d314de4b Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 28 Oct 2021 17:53:05 +0300 Subject: [PATCH 52/60] LiveCare Schedule fixes --- .../schedule_clinic_card.dart | 22 +++--- .../livecare_services/livecare_provider.dart | 78 ------------------- 2 files changed, 9 insertions(+), 91 deletions(-) diff --git a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart index 330fec35..7884b37e 100644 --- a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart +++ b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart @@ -39,7 +39,7 @@ class _ScheduleClinicCardState extends State { ), child: Container( decoration: BoxDecoration( - color: CustomColors.green , + color: CustomColors.green, borderRadius: BorderRadius.all( Radius.circular(6.0), ), @@ -49,11 +49,13 @@ class _ScheduleClinicCardState extends State { left: projectViewModel.isArabic ? 0 : widget.isSelected - ? 4 - : 6, - right: projectViewModel.isArabic ? widget.isSelected - ? 4 - : 6: 0), + ? 4 + : 6, + right: projectViewModel.isArabic + ? widget.isSelected + ? 4 + : 6 + : 0), padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), decoration: BoxDecoration( color: Colors.white, @@ -71,13 +73,7 @@ class _ScheduleClinicCardState extends State { children: [ Container( child: Text( - widget.languageID == 'ar' - ? widget.clinicsHaveScheduleList.clinicDescN != null - ? widget.clinicsHaveScheduleList.clinicDescN - : "" - : widget.clinicsHaveScheduleList.clinicDesc != null - ? widget.clinicsHaveScheduleList.clinicDesc - : "Test Clinic", + widget.clinicsHaveScheduleList.clinicDesc, style: TextStyle( fontSize: 16.0, color: Colors.black, diff --git a/lib/services/livecare_services/livecare_provider.dart b/lib/services/livecare_services/livecare_provider.dart index fa40bd57..6553da40 100644 --- a/lib/services/livecare_services/livecare_provider.dart +++ b/lib/services/livecare_services/livecare_provider.dart @@ -25,18 +25,7 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -60,18 +49,7 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - // "LanguageID": languageID == 'ar' ? 1 : 2, - // "IPAdress": "10.20.10.20", - // "VersionID": req.VersionID, - // "Channel": req.Channel, - // "generalid": 'Cs2020@2016\$2958', - // "PatientOutSA": 0, - // "TokenID": "", - // "DeviceTypeID": req.DeviceTypeID, - // "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -95,19 +73,8 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, "ServiceID": serviceID, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -154,18 +121,8 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, "ServiceID": serviceID, - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -189,21 +146,9 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, "ServiceID": serviceID, "ProjectID": 15, - "DeviceTypeID": req.DeviceTypeID, - "PatientType": authUser.patientType != null ? authUser.patientType : 0, - "PatientTypeID": authUser.patientType != null ? authUser.patientType : 0, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -227,21 +172,9 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, "ServiceID": serviceID, "ProjectID": 15, - "DeviceTypeID": req.DeviceTypeID, - "PatientType": authUser.patientType != null ? authUser.patientType : 0, - "PatientTypeID": authUser.patientType != null ? authUser.patientType : 0, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -271,15 +204,7 @@ class LiveCareService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, "ErServiceID": serviceID, "ClientRequestID": clientRequestID, "DeviceToken": deviceToken, @@ -287,9 +212,6 @@ class LiveCareService extends BaseService { "Latitude": "24.708488", "Longitude": "46.665925", "DeviceType": Platform.isIOS ? 'iOS' : 'Android', - "PatientType": authUser.patientType != null ? authUser.patientType : 0, - "PatientTypeID": authUser.patientType != null ? authUser.patientType : 0, - "SessionID": "YckwoXhUmWBsnHKEKig", "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 From 9d71793e8838880d547d9cbcd8fbb0f9586eefe7 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Sun, 31 Oct 2021 11:05:20 +0300 Subject: [PATCH 53/60] no message --- assets/images/new-design/tamara.png | Bin 0 -> 53024 bytes lib/config/localized_values.dart | 1 + lib/core/service/client/base_app_client.dart | 2 +- .../PackagesOffersServices.dart | 43 ++++++------ .../OfferAndPackagesCartPage.dart | 35 +++++----- .../packages_offers/OfferAndPackagesPage.dart | 2 +- lib/uitl/translations_delegate_base.dart | 2 + .../dialogs/radio_selection_dialog.dart | 2 +- lib/widgets/single_selection_dialog.dart | 65 +++++++++--------- 9 files changed, 80 insertions(+), 72 deletions(-) create mode 100644 assets/images/new-design/tamara.png diff --git a/assets/images/new-design/tamara.png b/assets/images/new-design/tamara.png new file mode 100644 index 0000000000000000000000000000000000000000..ab58e3acbaecbac0da7c3f3f651692e9001fb11f GIT binary patch literal 53024 zcmeFZg;$jC);}x=Qqm=j2-2d!&?zNDcXu;V(k&n&F(4o@bazU32}lgxDIuNG{oZ~# z&pPY)9DjenyB^kJm^EB;-+S+C?|tp~>^oRdUJ4VP6#c=22bj`t#FZaBKyH8V03j0f z5%7uRY-A?f)2h!rAs&4u_^JqyF5_M;XThVATn(fasXcBc5 zf6#=6pnnbSl`z8<)m8l5N%&Mh*0g?*H@T;uw#`yeR}`602?A=YN{P@lGAj-p>hOKpgtnxs(o~)sPiR^*4$%zGy zz#VU=wqw=lMHQNL3rBIJL1KFP>}XyBJC4W$1f>7^q8TYN1X3W_H+j4LlCEj7fL(pF zmK+^+|J$)PcX#Ks$ZY{!mu1{KfW|5Ge zgMCg^IQ}N2_xp%_@*f7{%L`!DYx~N&I2HW#knYOQYj^QWeyOe+52T*{jYU;G!|C9I zGKXd~|A*-QM`f=}N?!&9_%go{_~7?9ss4y;b;Ms%T0vqBbAMMpV`#^TEm+pXdoq?A zLP$LPSCJ6t8E%TZ`8F2kPeTZtirxHX2d$b9B8b>t(7gVe_Aq>H9RbL5k6uGw%qT;c zHRR?XxGN|-#C`HNS%@qlrO1B>It-FaQ<@B1;MDfEHw=0m^v3?L3KodxCP~xi5J&Xg zOEf)0$NXj69k5IEoe|NfxPMdY5bBqasHNTeuO@slQ4!=w1FD2UVh=qP>Z$nu%0D%= zU$D5_Sncb(`U-BE%(fhJeXm6BLp+ARvSN$q2Lo-poA-jx)`̿@$3vL;->Y_Wbm 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 Mq>@CXm{Gw01K-= body, Map headers, + Map body, Map headers, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, }) async { diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 17abdc05..d05bc274 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -147,6 +147,18 @@ class OffersAndPackagesServices extends BaseService { var finished = 0; var totalCalls = 3; + + completedAll(){ + + finished++; + if(completion != null && finished == totalCalls) { + _hideLoading(context, showLoading); + completion(); + } + } + + _showLoading(context, showLoading); + final auth_token = await baseAppClient.generatePackagesToken(); if(auth_token == null){ throw 'Something went wrong while authentication, Please try again letter'; @@ -162,18 +174,6 @@ class OffersAndPackagesServices extends BaseService { } } - - completedAll(){ - - finished++; - if(completion != null && finished == totalCalls) { - _hideLoading(context, showLoading); - completion(); - } - } - - _showLoading(context, showLoading); - // Performing Parallel Request on same time // # 1 getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ @@ -283,7 +283,7 @@ class OffersAndPackagesServices extends BaseService { var jsonResponse = json.decode(stringResponse); var jsonCartItem = jsonResponse["shopping_carts"][0]; response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); - cartItemCount = response.data.quantity.toString(); + cartItemCount = (jsonResponse['count'] ?? 0).toString(); }, onFailure: (String error, int statusCode){ _hideLoading(context, showLoading); @@ -334,19 +334,18 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Place Order // -------------------- - Future placeOrder({@required Map paymentParams, @required BuildContext context, bool showLoading = true}) async{ + Future placeOrder({@required Map paymentParams, @required BuildContext context, bool showLoading = true}) async{ Future errorThrow; - var jsonBody = { - "order": { - "customer_id" : customer.id, - "billing_address": { - "email": patientUser.emailAddress, - "phone_number": patientUser.mobileNumber - }, - } + Map jsonBody = { + "customer_id" : customer.id, + "billing_address": { + "email": patientUser.emailAddress, + "phone_number": patientUser.mobileNumber + }, }; jsonBody.addAll(paymentParams); + jsonBody = {'order' : jsonBody}; int order_id; _showLoading(context, showLoading); diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index 53b4895c..d1219541 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -87,7 +87,7 @@ class _PackagesCartPageState extends State 'Failed to place order, please try again later'); } }).catchError((error) { - utils.Utils.showErrorToast(error); + utils.Utils.showErrorToast(error.toString()); }); } @@ -217,7 +217,7 @@ class _PackagesCartPageState extends State {@required int orderId, @required bool withStatus, dynamic data}) async { viewModel.service.getOrderById(orderId, context: context).then((value) { var heading = withStatus ? "Success" : "Failed"; - var title = "Your order has been placed successfully"; + var title = withStatus ? "Your order has been placed successfully" : "Failed to place your order"; var subTitle = "Order# ${value.data.customOrderNumber}"; Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => PackageOrderCompletedPage( @@ -231,7 +231,7 @@ class _PackagesCartPageState extends State // /* Payment Footer Widgets */ // --------------------------- String _selectedPaymentMethod; -Map _selectedPaymentParams; +Map _selectedPaymentParams; Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) { double height = 30; @@ -258,7 +258,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa Future selectTamaraPaymentOption() async{ final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true); - final selected = await SingleSelectionDialog(tamara_options, title: 'Select the tamara installment plan').show(context); + final selected = await SingleSelectionDialog(tamara_options, icon: Image.asset('assets/images/new-design/tamara.png'), title: TranslationBase.of(context).tamaraInstPlan).show(context); return selected.name; } @@ -271,13 +271,16 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa mainAxisAlignment: MainAxisAlignment.center, children: [ InkWell( - child: buttonContent(_selectedPaymentMethod == "tamara", 'mada.png'), + child: buttonContent(_selectedPaymentMethod == "tamara", 'tamara.png'), onTap: () async{ final tamara_option = await selectTamaraPaymentOption(); _selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option}; onSelected("tamara"); }, ), + SizedBox( + width: 5, + ), InkWell( child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), onTap: () { @@ -305,17 +308,17 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa onSelected("mastercard"); }, ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent( - _selectedPaymentMethod == "installment", 'installment.png'), - onTap: () { - _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"}; - onSelected("installment"); - }, - ), + // SizedBox( + // width: 5, + // ), + // InkWell( + // child: buttonContent( + // _selectedPaymentMethod == "installment", 'installment.png'), + // onTap: () { + // _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"}; + // onSelected("installment"); + // }, + // ), ], ), ), diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart index 4005f835..dc5b6584 100644 --- a/lib/pages/packages_offers/OfferAndPackagesPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -98,7 +98,7 @@ class _PackagesHomePageState extends State with AfterLayoutMix await viewModel.service.addProductToCart(request, context: context).then((response){ appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); }).catchError((error) { - utils.Utils.showErrorToast(error); + utils.Utils.showErrorToast(error.toString()); }); } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 396afd00..aac73d71 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2563,6 +2563,8 @@ class TranslationBase { String get androidInstructions3 => localizedValues["android-instructions-3"][locale.languageCode]; String get androidInstructions4 => localizedValues["android-instructions-4"][locale.languageCode]; + + String get tamaraInstPlan => localizedValues["tamaraInstPlan"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/dialogs/radio_selection_dialog.dart b/lib/widgets/dialogs/radio_selection_dialog.dart index 4cbfdcc4..7175d6dc 100644 --- a/lib/widgets/dialogs/radio_selection_dialog.dart +++ b/lib/widgets/dialogs/radio_selection_dialog.dart @@ -110,7 +110,7 @@ class RadioSelectionDialogState extends State { Expanded( child: DefaultButton( TranslationBase.of(context).save, - () { + (){ Navigator.pop(context); widget.onValueSelected(selectedIndex); }, diff --git a/lib/widgets/single_selection_dialog.dart b/lib/widgets/single_selection_dialog.dart index b8466b65..155f6394 100644 --- a/lib/widgets/single_selection_dialog.dart +++ b/lib/widgets/single_selection_dialog.dart @@ -13,8 +13,9 @@ import 'package:permission_handler/permission_handler.dart'; class SingleSelectionDialog extends StatefulWidget { final List items; final String title; + final Widget icon; - SingleSelectionDialog(this.items, {Widget icon, @required this.title}); + SingleSelectionDialog(this.items, {@required this.icon, @required this.title}); Future show(BuildContext context) async { return showDialog( @@ -32,6 +33,7 @@ class SingleSelectionDialog extends StatefulWidget { @override _SingleSelectionDialogState createState() => _SingleSelectionDialogState(); + } class _SingleSelectionDialogState extends State { @@ -51,11 +53,12 @@ class _SingleSelectionDialogState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon( - Icons.notifications_active, - color: Color(0xff2B353E), - size: 50, + + SizedBox( + height: 40, + child: widget.icon, ), + IconButton( icon: Icon(Icons.clear), color: Color(0xff2B353E), @@ -95,33 +98,33 @@ class _SingleSelectionDialogState extends State { } Widget optionList(List options){ - return ListView( - shrinkWrap: true, - children: List.generate(options.length, (index){ - - final opt = options[index]; - return Row( - children: [ - Radio( - value: index, - groupValue: i, - onChanged: (int value) { - setState(() { - i = value; - }); - }, - ), - Text( - opt.toString(), - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - letterSpacing: -0.48, + return ListView.builder( + shrinkWrap: true, + itemCount: options.length, + itemBuilder: (ctx,idx){ + final opt = options[idx]; + return Row( + children: [ + Radio( + value: idx, + groupValue: i, + onChanged: (int value) { + setState(() { + i = value; + }); + }, ), - ), - ], - ); - }), + Text( + opt.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ); + } ); } } From 616748dc6f10369c2c1e996ce9c28216d36665ac Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 31 Oct 2021 10:41:27 +0200 Subject: [PATCH 54/60] fix proceed button --- lib/config/config.dart | 4 ++-- .../screens/cart-page/cart-order-preview.dart | 9 ++++++-- .../cart-page/select_address_widget.dart | 21 ++++++++----------- .../select_payment_option_widget.dart | 4 +++- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index bbbacaa4..8041ec47 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,8 +14,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart index 25c02dd0..4f5ab14e 100644 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart @@ -63,11 +63,11 @@ class _OrderPreviewPageState extends State { color: Color(0xFFF1F1F1), child: Column( children: [ - SelectAddressWidget(model, widget.addresses), + SelectAddressWidget(model, widget.addresses,changeMainState), SizedBox( height: 10, ), - SelectPaymentOptionWidget(model), + SelectPaymentOptionWidget(model, changeMainState), SizedBox( height: 10, ), @@ -235,4 +235,9 @@ class _OrderPreviewPageState extends State { ), ); } + changeMainState(){ + setState(() { + + }); + } } diff --git a/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart b/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart index bf958a36..d6182b9a 100644 --- a/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart +++ b/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -25,39 +26,35 @@ import 'package:provider/provider.dart'; class SelectAddressWidget extends StatefulWidget { final OrderPreviewViewModel model; final List addresses; + final Function changeMainState; - SelectAddressWidget(this.model, this.addresses); + SelectAddressWidget(this.model, this.addresses, this.changeMainState); @override _SelectAddressWidgetState createState() => _SelectAddressWidgetState(); } class _SelectAddressWidgetState extends State { - Addresses address; + AddressInfo address; _navigateToAddressPage() { Navigator.push(context, FadePage(page: PharmacyAddressesPage())) .then((result) { if (result != null) { address = result; - widget.model.paymentCheckoutData.address = address; + widget.model.paymentCheckoutData.address = + Addresses.fromJson(address.toJson()); widget.model.getInformationsByAddress(); + widget.changeMainState(); } - - /* setState(() { - if (result != null) { - address = result; - widget.model.paymentCheckoutData.address = address; - widget.model.getInformationsByAddress(); - } - })*/ }); } @override void initState() { if (widget.model.paymentCheckoutData.address != null) { - address = widget.model.paymentCheckoutData.address; + address = AddressInfo.fromJson( + widget.model.paymentCheckoutData.address.toJson()); } super.initState(); } diff --git a/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart b/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart index 9234bb38..7ccb12e5 100644 --- a/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart +++ b/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart @@ -24,8 +24,9 @@ import 'package:provider/provider.dart'; class SelectPaymentOptionWidget extends StatefulWidget { final OrderPreviewViewModel model; + final Function changeMainState; - SelectPaymentOptionWidget(this.model); + SelectPaymentOptionWidget(this.model, this.changeMainState); @override _SelectPaymentOptionWidgetState createState() => @@ -44,6 +45,7 @@ class _SelectPaymentOptionWidgetState extends State { widget.model.paymentCheckoutData.paymentOption = paymentOption; } + widget.changeMainState(); }) }); } From e6378b7ada0ee1c0cca7d554695d5c5c72cc70dc Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Sun, 31 Oct 2021 13:51:03 +0300 Subject: [PATCH 55/60] fix issues --- lib/config/localized_values.dart | 2 + lib/pages/final_products_page.dart | 505 +++++++++++------- lib/pages/offers_categorise_page.dart | 2 +- lib/pages/parent_categorise_page.dart | 4 +- .../screens/cart-page/cart-order-page.dart | 2 +- .../product-details/footor/footer-widget.dart | 166 +++--- .../shared/product_details_app_bar.dart | 2 +- lib/pages/pharmacies/search_brands_page.dart | 35 +- .../pharmacies/widgets/ProductTileItem.dart | 56 +- .../widgets/home/PrescriptionsWidget.dart | 6 +- lib/pages/search_products_page.dart | 29 +- lib/pages/sub_categorise_page.dart | 4 +- lib/uitl/translations_delegate_base.dart | 4 + 13 files changed, 507 insertions(+), 310 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7f77d115..f73e5fe2 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -759,6 +759,8 @@ const Map localizedValues = { "location-permission": {"en": "Location", "ar": "تحديد المواقع"}, "needPrescription": {"en": "This product requires a prescription", "ar": " هذا المنتج يتطلب وصفة طبية"}, "outOfStockMsg": {"en": "You have added product which is out of stock now, Please remove that!", "ar": "لقد قمت بإضافة المنتج الذي نفذ من المخزون الآن. يرجى إزالة ذلك"}, + "noArabicLetters": {"en": "It Is Not Allow to Use Arabic Letters", "ar": "غير مسموح باستخدام الحروف العربيه"}, + "noOffersAvailable": {"en": "No Offers Available!", "ar": "لايوجد عروض حاليا"}, "accessibility": {"en": "Accessibility Mode", "ar": "وضع امكانية الوصول"}, "orderStatus": {"en": "Order Status", "ar": "حالة الطلب"}, "CancelOrder": {"en": "Cancel Order", "ar": "الغاء الطلب"}, diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 9c3a9e43..65adf282 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -198,7 +198,8 @@ class _FinalProductsPageState extends State { ), margin: EdgeInsets.symmetric( horizontal: 8, - vertical: 4, + vertical: 1, +// vertical: 2, ), child: Container( decoration: BoxDecoration( @@ -210,11 +211,17 @@ class _FinalProductsPageState extends State { color: Colors.white, ), padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, + horizontal: 4, + ), + width: MediaQuery.of(context).size.width / 3, +// width: MediaQuery.of(context) +// .size +// .width / +// 1, +// height: MediaQuery.of(context) +// .size +// .width / +// 1, child: Column( crossAxisAlignment: CrossAxisAlignment @@ -224,7 +231,7 @@ class _FinalProductsPageState extends State { children: [ Container( margin: EdgeInsets - .fromLTRB(0, 16, + .fromLTRB(0, 1, 0, 0), alignment: Alignment .center, @@ -242,10 +249,68 @@ class _FinalProductsPageState extends State { .thumb : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', fit: BoxFit.cover, - height: 80, + height: 70, ), ), - Container( +// Container( +// width: model +// .finalProducts[ +// index] +// .rxMessage != +// null +// ? MediaQuery.of( +// context) +// .size +// .width / +// 2.8 +// : 0, +// padding: +// EdgeInsets.all( +// 4), +// decoration: +// BoxDecoration( +// color: Color( +// 0xffb23838), +// borderRadius: BorderRadius.only( +// topLeft: Radius +// .circular( +// 6)), +// ), +// child: model +// .finalProducts[ +// index] +// .rxMessage != +// null +// ? Texts( +// languageID == +// 'ar' +// ? model +// .finalProducts[ +// index] +// .rxMessagen +// : model +// .finalProducts[index] +// .rxMessage, +// color: Colors +// .white, +// regular: +// true, +// fontSize: +// 10, +// fontWeight: +// FontWeight +// .w600, +// ) +// : Texts(""), +// ), + ], + ), + Container( + margin: EdgeInsets + .symmetric( + horizontal: 0, + vertical: 2, + ), width: model .finalProducts[ index] @@ -255,19 +320,18 @@ class _FinalProductsPageState extends State { context) .size .width / - 2.8 + 2.0 : 0, padding: - EdgeInsets.all( - 4), + EdgeInsets.fromLTRB(8,4,8,4), decoration: BoxDecoration( color: Color( 0xffb23838), - borderRadius: BorderRadius.only( - topLeft: Radius - .circular( - 6)), +// borderRadius: BorderRadius.only( +// topLeft: Radius +// .circular( +// 6)), ), child: model .finalProducts[ @@ -296,8 +360,6 @@ class _FinalProductsPageState extends State { ) : Texts(""), ), - ], - ), Container( margin: EdgeInsets .symmetric( @@ -439,205 +501,268 @@ class _FinalProductsPageState extends State { (BuildContext context, int index) { return InkWell( child: Card( - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets - .only( - left: 9.0, - top: 8.0, - right: 10.0, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets + .only( + left: 2.0, + top: 2.0, + right: 2.0, + ), ), ), - ), - Container( - margin: EdgeInsets - .fromLTRB( - 0, 0, 0, 0), - alignment: Alignment - .center, - child: - Image.network( - model - .finalProducts[ - index] - .images - .isNotEmpty - ? model - .finalProducts[ - index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit - .contain, - height: 80, + Container( +// margin: EdgeInsets +// .fromLTRB( +// 8, 0, 8, 0), + alignment: Alignment + .center, + child: + Image.network( + model + .finalProducts[ + index] + .images + .isNotEmpty + ? model + .finalProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit + .contain, + height: 70, + ), ), - ), - ], + ], + ), +// Column( +// children: [ +// Container( +// width: model +// .finalProducts[ +// index] +// .rxMessage != +// null +// ? MediaQuery.of( +// context) +// .size +// .width / +// 5.3 +// : 0, +// padding: +// EdgeInsets.all( +// 4), +// decoration: +// BoxDecoration( +// color: Color( +// 0xffb23838), +// borderRadius: BorderRadius.only( +// topLeft: Radius +// .circular( +// 6)), +// ), +// child: Texts( +// model +// .finalProducts[ +// index] +// .rxMessage != +// null +// ? model +// .finalProducts[ +// index] +// .rxMessage +// : "", +// color: +// Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: +// FontWeight +// .w600, +// ), +// ), +// ], +// ), + + + + ], + ), + Container( + height: 130.0, + margin: + EdgeInsets.symmetric( + horizontal: 0, + vertical: 6, ), - Column( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + crossAxisAlignment: + CrossAxisAlignment + .start, children: [ + Container( + margin: EdgeInsets + .symmetric( + horizontal: 4, + vertical: 0, + ), width: model - .finalProducts[ - index] - .rxMessage != - null + .finalProducts[ + index] + .rxMessage != + null ? MediaQuery.of( - context) - .size - .width / - 5.3 + context) + .size + .width / + 2.0 : 0, padding: - EdgeInsets.all( - 4), + EdgeInsets.all( + 4), decoration: - BoxDecoration( + BoxDecoration( color: Color( 0xffb23838), - borderRadius: BorderRadius.only( - topLeft: Radius - .circular( - 6)), +// borderRadius: BorderRadius.only( +// topLeft: Radius +// .circular( +// 6)), ), + child: model + .finalProducts[ + index] + .rxMessage != + null + ? Texts( + languageID == + 'ar' + ? model + .finalProducts[ + index] + .rxMessagen + : model + .finalProducts[index] + .rxMessage, + color: Colors + .white, + regular: + true, + fontSize: + 10, + fontWeight: + FontWeight + .w600, + ) + : Texts(""), + ), + SizedBox( + height: 4.0, + ), + Container( + width: MediaQuery.of( + context) + .size + .width * + 0.65, child: Texts( model - .finalProducts[ - index] - .rxMessage != - null - ? model - .finalProducts[ - index] - .rxMessage - : "", - color: - Colors.white, + .finalProducts[ + index] + .name, regular: true, - fontSize: 10, + fontSize: 13.2, fontWeight: - FontWeight - .w600, + FontWeight.w500, + maxLines: 5, ), ), - ], - ), - ], - ), - Container( - height: 100.0, - margin: - EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - SizedBox( - height: 4.0, - ), - Container( - width: MediaQuery.of( - context) - .size - .width * - 0.65, - child: Texts( - model - .finalProducts[ - index] - .name, - regular: true, - fontSize: 13.2, - fontWeight: - FontWeight.w500, - maxLines: 5, + SizedBox( + height: 8.0, ), - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.finalProducts[index].price}", - bold: true, - fontSize: 14, + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: 4), + child: Texts( + "SAR ${model.finalProducts[index].price}", + bold: true, + fontSize: 14, + ), ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .finalProducts[ - index] - .approvedRatingSum > - 0 - ? (model.finalProducts[index].approvedRatingSum.toDouble() / - model.finalProducts[index].approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: - true), - Texts( - "(${model.finalProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight - .w400, - ) - ], - ), - ], + Row( + children: [ + StarRating( + totalAverage: model + .finalProducts[ + index] + .approvedRatingSum > + 0 + ? (model.finalProducts[index].approvedRatingSum.toDouble() / + model.finalProducts[index].approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: + true), + Texts( + "(${model.finalProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight + .w400, + ) + ], + ), + ], + ), ), - ), - widget.authenticatedUserObject.isLogin - ? Container( - child: IconButton( - icon: Icon(Icons.shopping_cart, - size: 18, - color: Colors.blue,), - onPressed: () async { - if(model.finalProducts[index].rxMessage == null){ - GifLoaderDialogUtils.showMyDialog(context); - await addToCartFunction(1, model.finalProducts[index].id); - GifLoaderDialogUtils.hideDialog(context); - Navigator.push( - context, - FadePage(page: CartOrderPage())); + widget.authenticatedUserObject.isLogin + ? Container( + child: IconButton( + icon: Icon(Icons.shopping_cart, + size: 18, + color: Colors.blue,), + onPressed: () async { + if(model.finalProducts[index].rxMessage == null){ + GifLoaderDialogUtils.showMyDialog(context); + await addToCartFunction(1, model.finalProducts[index].id); + GifLoaderDialogUtils.hideDialog(context); + Navigator.push( + context, + FadePage(page: CartOrderPage())); + } + else{ + AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); } - else{ - AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); - } // - } + } - ), - ):Container(), - ], + ), + ):Container(), + ], + ), ), ), onTap: () => { diff --git a/lib/pages/offers_categorise_page.dart b/lib/pages/offers_categorise_page.dart index 24ff4355..2715b2b0 100644 --- a/lib/pages/offers_categorise_page.dart +++ b/lib/pages/offers_categorise_page.dart @@ -713,7 +713,7 @@ class _OffersCategorisePageState extends State { ), Padding( padding: const EdgeInsets.all(8.0), - child: Text(TranslationBase.of(context).noData, + child: Text(TranslationBase.of(context).noOffersAvailable, // 'There is no data', style: TextStyle(fontSize: 30), ), diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index c40fa6bd..b63319f5 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -1031,7 +1031,7 @@ class _ParentCategorisePageState extends State { .thumb : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', fit: BoxFit.contain, - height: 80, + height: 70, ), ), ], @@ -1086,7 +1086,7 @@ class _ParentCategorisePageState extends State { ), Container( margin: EdgeInsets.symmetric( - horizontal: 6, + horizontal: 0, vertical: 0, ), child: Column( diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart index a15c5c50..79165766 100644 --- a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart @@ -421,7 +421,7 @@ class _OrderBottomWidgetState extends State { fontSize: 14), ), color: Color(0xFF4CAF50), - disabledColor:Colors.grey[700], + disabledColor:Color(0xFF848484), // disabledColor: Color(0xff005aff), ) // RaisedButton( diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart index 69f16ac2..b8bc5808 100644 --- a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -128,92 +128,104 @@ class _FooterWidgetState extends State { : Container( height: 20, ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 70, - height: 50, - child: FlatButton( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 4, - child: Text( - widget.quantity.toString(), - style: TextStyle(fontSize: 20), + Container( + height: 58, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 90, + height: 60, + child: FlatButton( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 4, + child: Text( + widget.quantity.toString(), + style: TextStyle(fontSize: 20), + ), ), - ), - Expanded( - flex: 5, - child: Text( - TranslationBase.of(context).quantityShortcut, - style: TextStyle(fontSize: 16), + Expanded( + flex: 5, + child: Text( + TranslationBase.of(context).quantityShortcut, + style: TextStyle(fontSize: 16), + ), ), - ), - ], + ], + ), + onPressed: () { + setState(() { + if (showUI) { + quantityUI = 80; + showUI = false; + } else { + quantityUI = 160; + showUI = true; + } + }); + }, ), - onPressed: () { - setState(() { - if (showUI) { - quantityUI = 80; - showUI = false; - } else { - quantityUI = 160; - showUI = true; - } - }); - }, ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.45, - child: SecondaryButton( - label: TranslationBase.of(context).addToCart.toUpperCase(), - disabled: (!widget.isAvailable && widget.quantity > 0) || widget.quantity > widget.quantityLimit || widget.item.isRx, - onTap: () async { - if (!authenticatedUserObject.isLogin) { - Navigator.of(context).pushNamed( - WELCOME_LOGIN, - ); - } else - await widget.addToCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); - }, - fontWeight: FontWeight.w600, - borderColor: Color(0xFF4CAF50), - borderRadius: 3, - color: Color(0xFF4CAF50), + SizedBox( + width: 10, ), - ), - SizedBox( - width: 5, - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - child: SecondaryButton( - label: TranslationBase.of(context).buyNow.toUpperCase(), - disabled: (!widget.isAvailable && widget.quantity > 0) || (widget.quantity > widget.quantityLimit) || widget.item.isRx, - onTap: () async { - await widget.addToShoppingCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); - Navigator.push( - context, - FadePage(page: CartOrderPage()), - ); - }, - fontWeight: FontWeight.w600, - borderColor: Colors.grey[800], - borderRadius: 3, - disableColor: Colors.grey[700], - color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || widget.item.rxMessage != null ? Colors.grey : Colors.grey[800], + Container( + width: MediaQuery.of(context).size.width * 0.35, + child: SecondaryButton( + label: TranslationBase.of(context).addToCart.toUpperCase(), + disabled: (!widget.isAvailable && widget.quantity > 0) || widget.quantity > widget.quantityLimit || widget.item.isRx, + onTap: () async { + if (!authenticatedUserObject.isLogin) { + Navigator.of(context).pushNamed( + WELCOME_LOGIN, + ); + } else + await widget.addToCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); + }, + fontWeight: FontWeight.w600, + borderColor: Color(0xFF4CAF50), + borderRadius: 3, + color: Color(0xFF4CAF50), + ), + ), + SizedBox( + width: 5, + ), + Container( + width: MediaQuery.of(context).size.width * 0.35, + child: SecondaryButton( + label: TranslationBase.of(context).buyNow.toUpperCase(), + disabled: (!widget.isAvailable && widget.quantity > 0) || (widget.quantity > widget.quantityLimit) || widget.item.isRx, + onTap: () async { + if (!authenticatedUserObject.isLogin) { + Navigator.of(context).pushNamed( + WELCOME_LOGIN, + ); + } else { + await widget.addToShoppingCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); + Navigator.push( + context, + FadePage(page: CartOrderPage()), + );} + }, + fontWeight: FontWeight.w600, + borderColor: Colors.grey[800], + borderRadius: 3, + disableColor: Colors.grey[700], + color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || widget.item.rxMessage != null ? Colors.grey : Colors.grey[800], + ), ), - ), - ], + ], + ), ), ], ), + ); } diff --git a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart index 5febe30c..22fcec7f 100644 --- a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -78,7 +78,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { borderRadius: BorderRadius.circular(15), ), padding: EdgeInsets.only(left: 5, right: 4.5), - height: 18, + height: 19, child: Center( child: Texts( Provider.of(context, listen: false).cartResponse.quantityCount.toString(), diff --git a/lib/pages/pharmacies/search_brands_page.dart b/lib/pages/pharmacies/search_brands_page.dart index d993ecdf..cb1281ff 100644 --- a/lib/pages/pharmacies/search_brands_page.dart +++ b/lib/pages/pharmacies/search_brands_page.dart @@ -1,11 +1,14 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; class SearchBrandsPage extends StatefulWidget { @override @@ -23,7 +26,7 @@ class _SearchBrandsPageState extends State { onModelReady: (model) => model.searchProducts(), builder: (BuildContext context, model, Widget child) => PharmacyAppScaffold( - appBarTitle: 'Search', + appBarTitle: TranslationBase.of(context).search, isBottomBar: false, isShowAppBar: true, backgroundColor: Colors.white, @@ -44,24 +47,36 @@ class _SearchBrandsPageState extends State { key: _formKey, child: TextFields( autoFocus: true, - hintText: 'Search', + hintText: TranslationBase.of(context).search, fontSize: 19.0, prefixIcon: Icon(Icons.search), inputAction: TextInputAction.search, + inputFormatters: [ + FilteringTextInputFormatter.deny(RegExp("[\u0621-\u064a-\ ]")) + ], + validator: (value) { + RegExp regExp = RegExp('[\u0621-\u064a-\ ]'); + if (value.isEmpty) { + TranslationBase.of(context).pleaseEnterProductName; + }else if (regExp.hasMatch(value)){ + AppToast.showErrorToast(message: TranslationBase.of(context).noArabicLetters); + } + return null; + }, onSaved: (value) { //searchMedicine(model, context); }, onSubmit: (value) { searchMedicine(model, context); - msg = 'No Result Found'; + msg = TranslationBase.of(context).noResultFound; }, controller: textController, - validator: (value) { - if (value.isEmpty) { - return 'please Enter Product Name'; - } - return null; - }, +// validator: (value) { +// if (value.isEmpty) { +// return 'please Enter Product Name'; +// } +// return null; +// }, ), ), ), @@ -70,7 +85,7 @@ class _SearchBrandsPageState extends State { ), InkWell( child: Texts( - 'Cancel', + TranslationBase.of(context).cancel, fontSize: 17.0, fontWeight: FontWeight.w500, ), diff --git a/lib/pages/pharmacies/widgets/ProductTileItem.dart b/lib/pages/pharmacies/widgets/ProductTileItem.dart index 92ad8d1a..56b4cc7e 100644 --- a/lib/pages/pharmacies/widgets/ProductTileItem.dart +++ b/lib/pages/pharmacies/widgets/ProductTileItem.dart @@ -88,7 +88,7 @@ class ProductTileItem extends StatelessWidget { Stack( children: [ Container( - margin: EdgeInsets.fromLTRB(0, 16, 0, 0), + margin: EdgeInsets.fromLTRB(0, 0, 0, 0), alignment: Alignment.center, child: (item.images != null && item.images.length > 0) ? Image.network( @@ -102,17 +102,42 @@ class ProductTileItem extends StatelessWidget { height: itemHeight / 2, ), ), - Container( - width: item.rxMessage != null - ? MediaQuery.of(context).size.width / 5 - : 0, - padding: EdgeInsets.all(4), +// Container( +// width: item.rxMessage != null +// ? MediaQuery.of(context).size.width / 5 +// : 0, +// padding: EdgeInsets.all(4), +// decoration: BoxDecoration( +// color: Color(0xffb23838), +// borderRadius: +// BorderRadius.only(topLeft: Radius.circular(6)), +// ), +// child: item.rxMessage != null +// ? Texts( +// projectProvider.isArabic +// ? item.rxMessagen +// : item.rxMessage, +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ) +// : Texts(""), +// ) + ], + ), + Padding( + padding: EdgeInsets.fromLTRB(4,2,4,2), + child: Container( +// width: item.rxMessage != null +// ? MediaQuery.of(context).size.width / 5 +// : 0, + // padding: EdgeInsets.fromLTRB(6,4,6,4), decoration: BoxDecoration( color: Color(0xffb23838), - borderRadius: - BorderRadius.only(topLeft: Radius.circular(6)), + ), - child: item.rxMessage != null + child: item.rxMessage != null ? Texts( projectProvider.isArabic ? item.rxMessagen @@ -123,12 +148,11 @@ class ProductTileItem extends StatelessWidget { fontWeight: FontWeight.w400, ) : Texts(""), - ) - ], - ), - SizedBox(height: 8,), + ), + ), + // SizedBox(height: 4,), Padding( - padding: const EdgeInsets.symmetric(horizontal: 6.0), + padding: const EdgeInsets.symmetric(horizontal: 4.0), child: Texts( projectProvider.isArabic ? item.namen : item.name, regular: true, @@ -139,7 +163,7 @@ class ProductTileItem extends StatelessWidget { Expanded( child: Container( margin: EdgeInsets.symmetric( - horizontal: 6, + horizontal: 4, vertical: 0, ), child: Column( @@ -147,7 +171,7 @@ class ProductTileItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ Padding( - padding: const EdgeInsets.only(top: 4, bottom: 4), + padding: const EdgeInsets.only(top: 2, bottom: 2), child: Texts( "SAR ${item.price}", fontWeight: FontWeight.w600, diff --git a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart index 04449cfd..261f4e99 100644 --- a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart +++ b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart @@ -36,7 +36,7 @@ class PrescriptionsWidget extends StatelessWidget { ViewAllHomeWidget(TranslationBase.of(context).myPrescription, HomePrescriptionsPage()), Container( margin: EdgeInsets.only(right: 10.0, left: 10.0), - height: MediaQuery.of(context).size.height * 0.20, + height: MediaQuery.of(context).size.height * 0.28, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, @@ -63,7 +63,7 @@ class PrescriptionsWidget extends StatelessWidget { top: 10.0, left: 10.0, right: 10.0, - bottom: 15.0, + bottom: 10.0, ), child: CircleAvatar( radius: 30, @@ -85,7 +85,7 @@ class PrescriptionsWidget extends StatelessWidget { border: Border.all( color: Colors.green, style: BorderStyle.solid, - width: 4.0, + width: 3.0, ), color: Colors.green, borderRadius: BorderRadius.circular(30.0)), diff --git a/lib/pages/search_products_page.dart b/lib/pages/search_products_page.dart index 0aac68a0..3fa00712 100644 --- a/lib/pages/search_products_page.dart +++ b/lib/pages/search_products_page.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_mo import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -12,6 +13,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'base/base_view.dart'; @@ -25,6 +27,7 @@ class _SearchProductsPageState extends State { final _formKey = GlobalKey(); String msg = ''; + @override Widget build(BuildContext context) { return BaseView( @@ -57,6 +60,18 @@ class _SearchProductsPageState extends State { fontSize: 14.5, prefixIcon: Icon(Icons.search), inputAction: TextInputAction.search, + inputFormatters: [ + FilteringTextInputFormatter.deny(RegExp("[\u0621-\u064a-\ ]")) + ], + validator: (value) { + RegExp regExp = RegExp('[\u0621-\u064a-\ ]'); + if (value.isEmpty) { + TranslationBase.of(context).pleaseEnterProductName; + }else if (regExp.hasMatch(value)){ + AppToast.showErrorToast(message: TranslationBase.of(context).noArabicLetters); + } + return null; + }, onSaved: (value) { //searchMedicine(model, context); }, @@ -66,13 +81,13 @@ class _SearchProductsPageState extends State { msg = TranslationBase.of(context).noResultFound; }, controller: textController, - validator: (value) { - if (value.isEmpty) { -// return 'please Enter Product Name'; - return TranslationBase.of(context).pleaseEnterProductName; - } - return null; - }, +// validator: (value) { +// if (value.isEmpty) { +//// return 'please Enter Product Name'; +// return TranslationBase.of(context).pleaseEnterProductName; +// } +// return null; +// }, ), ), ), diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index 90806a82..49ebf48d 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -987,9 +987,9 @@ class _SubCategorisePageState extends State { ], ), Container( - height: 100.0, + height: 130.0, margin: EdgeInsets.symmetric( - horizontal: 6, + horizontal: 0, vertical: 0, ), child: Column( diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 396afd00..82cc958c 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1765,6 +1765,10 @@ class TranslationBase { String get outOfStockMsg => localizedValues['outOfStockMsg'][locale.languageCode]; + String get noArabicLetters => localizedValues['noArabicLetters'][locale.languageCode]; + + String get noOffersAvailable => localizedValues['noOffersAvailable'][locale.languageCode]; + String get requestID => localizedValues['requestID'][locale.languageCode]; String get OrderStatus => localizedValues['OrderStatus'][locale.languageCode]; From 62974b7b72816aa8a67b1c49b2940da8c5317194 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 31 Oct 2021 13:59:17 +0300 Subject: [PATCH 56/60] Updates & fixes --- .../service/PrescriptionDeliveryService.dart | 6 +- .../medical/prescriptions_service.dart | 22 +- .../medical/prescriptions_view_model.dart | 6 +- .../health-weather-indicator.dart | 6 +- lib/pages/login/welcome.dart | 3 +- .../PrescriptionOrderOverveiw.dart | 62 ++-- .../prescription_details_page.dart | 11 +- .../prescriptions_history_page.dart | 241 ++++++------- .../prescriptions_home_page.dart | 4 +- lib/widgets/avatar/large_avatar.dart | 7 +- .../medical/time_line_new_widget.dart | 6 +- .../weather_slider/weather_slider.dart | 326 +++++++++++------- 12 files changed, 410 insertions(+), 290 deletions(-) diff --git a/lib/core/service/PrescriptionDeliveryService.dart b/lib/core/service/PrescriptionDeliveryService.dart index 104b390d..1d849755 100644 --- a/lib/core/service/PrescriptionDeliveryService.dart +++ b/lib/core/service/PrescriptionDeliveryService.dart @@ -25,9 +25,9 @@ class PrescriptionDeliveryService extends BaseService { Map body = Map(); body['latitude'] = latitude; body['longitude'] = longitude; - body['AppointmentNo'] = appointmentNo; - body['CreatedBy'] = createdBy; - body['DischargeID'] = dischargeID; + body['AppointmentNo'] = appointmentNo.toString(); + // body['CreatedBy'] = createdBy; + body['DischargeID'] = dischargeID.toString(); await baseAppClient.post(ADD_PRESCRIPTION_ORDER_RC, onSuccess: (dynamic response, int statusCode) { var asd = ""; }, onFailure: (String error, int statusCode) { diff --git a/lib/core/service/medical/prescriptions_service.dart b/lib/core/service/medical/prescriptions_service.dart index fa2a24c6..48c4f1bf 100644 --- a/lib/core/service/medical/prescriptions_service.dart +++ b/lib/core/service/medical/prescriptions_service.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/perscription_pharmacy.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; @@ -16,8 +17,9 @@ import 'package:flutter/cupertino.dart'; class PrescriptionsService extends BaseService { List prescriptionsList = List(); List prescriptionReportListINP = List(); - List prescriptionsOrderList = List(); + List prescriptionsOrderList = List(); var isMedDeliveryAllowed; + Future getPrescriptions() async { hasError = false; Map body = Map(); @@ -36,10 +38,24 @@ class PrescriptionsService extends BaseService { Future getPrescriptionsOrders() async { prescriptionsOrderList.clear(); Map body = Map(); - body['isDentalAllowedBackend'] = false; + // body['isDentalAllowedBackend'] = false; await baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, onSuccess: (dynamic response, int statusCode) { response['PatientER_GetPatientAllPresOrdersList'].forEach((prescriptionsOrder) { - prescriptionsOrderList.add(PrescriptionsOrder.fromJson(prescriptionsOrder)); + // prescriptionsOrderList.add(PrescriptionsOrder.fromJson(prescriptionsOrder)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getPrescriptionsOrdersRC() async { + prescriptionsOrderList.clear(); + Map body = Map(); + // body['isDentalAllowedBackend'] = false; + await baseAppClient.post(GET_ALL_PRESCRIPTION_ORDERS_RC, onSuccess: (dynamic response, int statusCode) { + response['response'].forEach((prescriptionsOrder) { + prescriptionsOrderList.add(GetCMCAllOrdersResponseModel.fromJson(prescriptionsOrder)); }); }, onFailure: (String error, int statusCode) { hasError = true; diff --git a/lib/core/viewModels/medical/prescriptions_view_model.dart b/lib/core/viewModels/medical/prescriptions_view_model.dart index 03018878..be6153bd 100644 --- a/lib/core/viewModels/medical/prescriptions_view_model.dart +++ b/lib/core/viewModels/medical/prescriptions_view_model.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/perscription_pharmacy.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; @@ -26,7 +27,7 @@ class PrescriptionsViewModel extends BaseViewModel { List get prescriptionsList => _prescriptionsService.prescriptionsList; - List get prescriptionsHistory => _prescriptionsService.prescriptionsOrderList; + List get prescriptionsHistory => _prescriptionsService.prescriptionsOrderList; List get pharmacyPrescriptionsList => _prescriptionsService.pharmacyPrescriptionsList; @@ -79,7 +80,8 @@ class PrescriptionsViewModel extends BaseViewModel { getPrescriptionsOrders({bool showLoading = false}) async { setState(ViewState.Busy); Future.delayed(new Duration(milliseconds: 300)).then((value) async { - await _prescriptionsService.getPrescriptionsOrders(); + // await _prescriptionsService.getPrescriptionsOrders(); + await _prescriptionsService.getPrescriptionsOrdersRC(); if (_prescriptionsService.hasError) { error = _prescriptionsService.error; setState(ViewState.ErrorLocal); diff --git a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart index d85db81f..bbd73d64 100644 --- a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart +++ b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart @@ -27,6 +27,8 @@ class _HospitalsPageState extends State { LocationUtils locationUtils; var weather = '--'; + ProjectViewModel projectViewModel; + @override void initState() { locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); @@ -37,7 +39,7 @@ class _HospitalsPageState extends State { @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getWeatherData(), allowAny: true, @@ -131,7 +133,7 @@ class _HospitalsPageState extends State { padding: EdgeInsets.all(15), child: Column( children: mode.weatherIndicatorData.map((data) { - return WeatherSlider(data); + return WeatherSlider(data, projectViewModel); }).toList())) ])) : Center(child: AppCircularProgressIndicator())), diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 26b6421c..8688fec3 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; +import 'package:diplomaticquarterapp/pages/login/register_new.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; @@ -78,7 +79,7 @@ class _WelcomeLogin extends State { child: DefaultButton( TranslationBase.of(context).no, () => { - Navigator.of(context).push(FadePage(page: Register())), + Navigator.of(context).push(FadePage(page: RegisterNew())), }, color: CustomColors.accentColor, textColor: Colors.white, diff --git a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart index 986fb848..719b2196 100644 --- a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart +++ b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart @@ -9,9 +9,10 @@ import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/show_zoom_image_dialog.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -101,23 +102,43 @@ class PrescriptionOrderOverview extends StatelessWidget { prescriptionReportEnhList.length, (index) => Container( margin: EdgeInsets.all(0.0), - decoration: cardRadius(0), + // decoration: cardRadius(0), child: Row( children: [ - Container( - margin: EdgeInsets.only(bottom: 10.0), - decoration: BoxDecoration( - border: Border.all(width: 1.0, color: Color(0xffEBEBEB)), - borderRadius: BorderRadius.all(Radius.circular(30.0)), - ), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: Image.network( - prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 48, - height: 48, - ), + InkWell( + onTap: () { + showZoomImageDialog(context, prescriptionReportEnhList[index].imageSRCUrl); + }, + child: Stack( + alignment: Alignment.center, + children: [ + Container( + margin: EdgeInsets.only(bottom: 10.0), + decoration: BoxDecoration( + border: Border.all(width: 1.0, color: Color(0xffEBEBEB)), + borderRadius: BorderRadius.all(Radius.circular(30.0)), + ), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(30)), + child: Image.network( + prescriptionReportEnhList[index].imageSRCUrl, + fit: BoxFit.cover, + width: 48, + height: 48, + ), + ), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Icon( + Icons.search, + size: 18, + color: Colors.white, + ), + padding: EdgeInsets.all(3), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), ), SizedBox(width: 14), @@ -153,15 +174,14 @@ class PrescriptionOrderOverview extends StatelessWidget { ), ), Container( - decoration: cardRadius(0), + // decoration: cardRadius(0), margin: EdgeInsets.zero, child: Container( width: double.infinity, margin: EdgeInsets.all(12), - child: SecondaryButton( - label: TranslationBase.of(context).submit.toUpperCase(), - color: CustomColors.accentColor, - onTap: () async { + child: DefaultButton( + TranslationBase.of(context).submit.toUpperCase(), + () async { showDialog( context: context, child: ConfirmWithMessageDialog( diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart index 3fbc2baf..5a47ec3b 100644 --- a/lib/pages/medical/prescriptions/prescription_details_page.dart +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -23,6 +23,7 @@ import 'package:provider/provider.dart'; class PrescriptionDetailsPage extends StatelessWidget { final PrescriptionReport prescriptionReport; final Prescriptions prescriptions; + PrescriptionDetailsPage({Key key, this.prescriptionReport, this.prescriptions}); @override @@ -111,14 +112,18 @@ class PrescriptionDetailsPage extends StatelessWidget { decoration: cardRadius(2000), ), Container( - child: Icon(Icons.search,size: 18,color: Colors.white,), + child: Icon( + Icons.search, + size: 18, + color: Colors.white, + ), padding: EdgeInsets.all(6), decoration: containerRadius(Colors.black.withOpacity(0.3), 200), ) ], ), - onTap: (){ - showZoomImageDialog(context, prescriptionReport.imageSRCUrl); + onTap: () { + showZoomImageDialog(context, prescriptionReport.imageSRCUrl); }, ), SizedBox(width: 12), diff --git a/lib/pages/medical/prescriptions/prescriptions_history_page.dart b/lib/pages/medical/prescriptions/prescriptions_history_page.dart index 1da0adb6..adce13bb 100644 --- a/lib/pages/medical/prescriptions/prescriptions_history_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_history_page.dart @@ -1,12 +1,11 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_details_page.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -25,126 +24,130 @@ class PrescriptionsHistoryPage extends StatelessWidget { onModelReady: (model) => model.getPrescriptionsOrders(showLoading: true), builder: (_, model, widget) => AppScaffold( baseViewModel: prescriptionsViewModel, - body: ListView.separated( - physics: BouncingScrollPhysics(), - padding: EdgeInsets.all(21), - separatorBuilder: (context, index) { - return SizedBox(height: 12); - }, - itemBuilder: (context, index) { - int status = prescriptionsViewModel.prescriptionsHistory[index].status; - String _statusDisp = projectViewModel.isArabic ? prescriptionsViewModel.prescriptionsHistory[index].descriptionN : prescriptionsViewModel.prescriptionsHistory[index].description; - Color _color; - if (status == 1) { - //pending - _color = Color(0xffCC9B14); - } else if (status == 2) { - //processing - _color = Color(0xff2E303A); - } else if (status == 3) { - //completed - _color = Color(0xff359846); - } else if (status == 4) { - //cancel // Rejected - _color = Color(0xffD02127); - } + body: model.state != ViewState.Busy + ? prescriptionsViewModel.prescriptionsHistory.length > 0 + ? ListView.separated( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + separatorBuilder: (context, index) { + return SizedBox(height: 12); + }, + itemBuilder: (context, index) { + int status = prescriptionsViewModel.prescriptionsHistory[index].statusId; + String _statusDisp = prescriptionsViewModel.prescriptionsHistory[index].statusText; + Color _color; + if (status == 1) { + //pending + _color = Color(0xffCC9B14); + } else if (status == 2) { + //processing + _color = Color(0xff2E303A); + } else if (status == 3) { + //completed + _color = Color(0xff359846); + } else if (status == 4 || status == 6 || status == 7) { + //cancel // Rejected + _color = Color(0xffD02127); + } - return InkWell( - onTap: () async { - final result = await Navigator.push( - context, - FadePage( - page: PrescriptionsHistoryDetailsPage( - prescriptionsOrder: prescriptionsViewModel.prescriptionsHistory[index], - ), - ), - ); - if (result != null) { - showOrderLog(); - } - }, - child: Container( - height: 65, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - boxShadow: [ - BoxShadow( - color: Color(0xff000000).withOpacity(.05), - blurRadius: 27, - offset: Offset(0, -3), - ), - ], - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - width: 6, - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), - bottomLeft: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), - topRight: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0), - bottomRight: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0), - ), - ), - ), - Expanded( - child: Padding( - padding: EdgeInsets.only(left: projectViewModel.isArabic ? 6 : 12, right: projectViewModel.isArabic ? 12 : 6), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _statusDisp, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), - ), - Text( - '${TranslationBase.of(context).orderNo}. ${prescriptionsViewModel.prescriptionsHistory[index].iD}', - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), - ), - ], - ), + return InkWell( + onTap: () async { + // final result = await Navigator.push( + // context, + // FadePage( + // page: PrescriptionsHistoryDetailsPage( + // prescriptionsOrder: prescriptionsViewModel.prescriptionsHistory[index], + // ), + // ), + // ); + // if (result != null) { + // showOrderLog(); + // } + }, + child: Container( + height: 65, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - DateUtil.getDayMonthYearDateFormatted(prescriptionsViewModel.prescriptionsHistory[index].createdOn), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 6, + decoration: BoxDecoration( + color: _color, + borderRadius: BorderRadius.only( + topLeft: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), + bottomLeft: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), + topRight: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0), + bottomRight: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0), + ), ), - Text( - DateUtil.formatDateToTimeLang(prescriptionsViewModel.prescriptionsHistory[index].createdOn, false), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: projectViewModel.isArabic ? 6 : 12, right: projectViewModel.isArabic ? 12 : 6), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + Text( + '${TranslationBase.of(context).orderNo}. ${prescriptionsViewModel.prescriptionsHistory[index].iD}', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ], + ), + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(prescriptionsViewModel.prescriptionsHistory[index].created)), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + Text( + DateUtil.formatDateToTimeLang(DateTime.tryParse(prescriptionsViewModel.prescriptionsHistory[index].created), false), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + ], + ) + ], + ), ), - ], - ) - ], - ), - ), - ), - Icon( - Icons.arrow_forward, - size: 16, - ), - mWidth(6), - ], - ), - )); - }, - itemCount: prescriptionsViewModel.prescriptionsHistory.length, - ), + ), + Icon( + Icons.arrow_forward, + size: 16, + ), + mWidth(6), + ], + ), + )); + }, + itemCount: prescriptionsViewModel.prescriptionsHistory.length, + ) + : getNoDataWidget(context) + : Container(), )); } } diff --git a/lib/pages/medical/prescriptions/prescriptions_home_page.dart b/lib/pages/medical/prescriptions/prescriptions_home_page.dart index 26c8dc22..d5efa38b 100644 --- a/lib/pages/medical/prescriptions/prescriptions_home_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_home_page.dart @@ -90,7 +90,7 @@ class _HomePrescriptionsPageState extends State with Sing prescriptionsViewModel: model, showOrderLog: () async { _tabController.animateTo(2); - await model.getPrescriptionsOrders(showLoading: true); + // await model.getPrescriptionsOrders(showLoading: true); setState(() {}); }, ), @@ -99,7 +99,7 @@ class _HomePrescriptionsPageState extends State with Sing prescriptionsViewModel: model, showOrderLog: () async { _tabController.animateTo(2); - await model.getPrescriptionsOrders(showLoading: true); + // await model.getPrescriptionsOrders(showLoading: true); setState(() {}); }, ), diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart index 64b72f2b..131a2820 100644 --- a/lib/widgets/avatar/large_avatar.dart +++ b/lib/widgets/avatar/large_avatar.dart @@ -14,11 +14,12 @@ import '../show_zoom_image_dialog.dart'; /// [height] the avatar height /// [onTap] on tap function class LargeAvatar extends StatelessWidget { - LargeAvatar({Key key, @required this.name, this.url, this.disableProfileView: false, this.radius = 70.0, this.width = 70, this.height = 60, this.onTap}) : super(key: key); + LargeAvatar({Key key, @required this.name, this.url, this.disableProfileView: false, this.radius = 70.0, this.width = 70, this.height = 60, this.onTap, this.isAppointmentAvatar: false}) : super(key: key); final String name; final String url; final bool disableProfileView; + final bool isAppointmentAvatar; final double radius; final double width; final double height; @@ -38,7 +39,7 @@ class LargeAvatar extends StatelessWidget { width: width, height: height, ), - if (!disableProfileView) + if (!disableProfileView && !isAppointmentAvatar) Container( child: Icon(Icons.search,size: 18,color: Colors.white,), padding: EdgeInsets.all(6), @@ -62,7 +63,7 @@ class LargeAvatar extends StatelessWidget { return InkWell( onTap: disableProfileView ? null - : () { + : isAppointmentAvatar ? onTap : () { print("ssssss " + url.trim()); showZoomImageDialog(context, url.trim() ?? ""); }, diff --git a/lib/widgets/data_display/medical/time_line_new_widget.dart b/lib/widgets/data_display/medical/time_line_new_widget.dart index 3851f329..4d38de2e 100644 --- a/lib/widgets/data_display/medical/time_line_new_widget.dart +++ b/lib/widgets/data_display/medical/time_line_new_widget.dart @@ -35,6 +35,7 @@ class _TimeLineViewState extends State { List dateObjs = []; DateObj selectedDateObj = null; final authService = new auth.AuthProvider(); + @override void initState() { super.initState(); @@ -347,14 +348,15 @@ class TimelineNewWidget extends StatelessWidget { FadePage( page: AppointmentDetails( appo: appoitmentAllHistoryResul, - parentIndex: 2, + parentIndex: 2, ))); }, name: appoitmentAllHistoryResul.doctorNameObj, - disableProfileView: true, + disableProfileView: false, url: appoitmentAllHistoryResul.doctorImageURL, width: 30, height: 30, + isAppointmentAvatar: true, ), mHeight(6), Text( diff --git a/lib/widgets/weather_slider/weather_slider.dart b/lib/widgets/weather_slider/weather_slider.dart index fe82cf49..0e784a05 100644 --- a/lib/widgets/weather_slider/weather_slider.dart +++ b/lib/widgets/weather_slider/weather_slider.dart @@ -1,47 +1,29 @@ import 'package:diplomaticquarterapp/core/model/weahter/weather_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class WeatherSlider extends StatelessWidget { - // final width; - // final LinearGradient color; final GetCityInfoList data; - WeatherSlider(this.data); - LinearGradient red = LinearGradient( - colors: [ - Colors.redAccent[100], - Colors.redAccent - ]); - LinearGradient green = LinearGradient( - colors: [ - Colors.greenAccent[100], - Colors.greenAccent - ]); - LinearGradient grey = LinearGradient( - colors: [ - Colors.grey[100], - Colors.grey - ]); - LinearGradient orange = LinearGradient( - colors: [ - Colors.orangeAccent[100], - Colors.orange - ]); - LinearGradient yellow = LinearGradient( - colors: [ - Colors.yellow[100], - Colors.yellow[600] - ]); + + final ProjectViewModel projectViewModel; + + WeatherSlider(this.data, this.projectViewModel); + + LinearGradient red = LinearGradient(colors: [Colors.redAccent[100], Colors.redAccent]); + LinearGradient green = LinearGradient(colors: [Colors.greenAccent[100], Colors.greenAccent]); + LinearGradient grey = LinearGradient(colors: [Colors.grey[100], Colors.grey]); + LinearGradient orange = LinearGradient(colors: [Colors.orangeAccent[100], Colors.orange]); + LinearGradient yellow = LinearGradient(colors: [Colors.yellow[100], Colors.yellow[600]]); + @override Widget build(BuildContext context) { // TODO: implement build return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.only(top:10), - child: AppText(data.name)), + Padding(padding: EdgeInsets.only(top: 10), child: AppText(data.name)), AppText( data.category, fontSize: 24, @@ -51,11 +33,8 @@ class WeatherSlider extends StatelessWidget { child: Stack( children: [ Container( - margin: EdgeInsets.only(bottom:10), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [Colors.grey[100], Colors.grey[400]]), - borderRadius: BorderRadius.circular(10)), + margin: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.grey[100], Colors.grey[400]]), borderRadius: BorderRadius.circular(10)), height: 15, width: MediaQuery.of(context).size.width, child: SizedBox(), @@ -64,110 +43,200 @@ class WeatherSlider extends StatelessWidget { top: 0, child: Container( decoration: BoxDecoration( - gradient: data.colorName =='red' ? red : data.colorName =='orange' ? orange : data.colorName =='green' ? green : data.colorName == 'yellow' ? yellow : grey, + gradient: data.colorName == 'red' + ? red + : data.colorName == 'orange' + ? orange + : data.colorName == 'green' + ? green + : data.colorName == 'yellow' + ? yellow + : grey, borderRadius: BorderRadius.circular(10)), height: 15, width: (MediaQuery.of(context).size.width * (double.parse(data.value) / 10)), padding: EdgeInsets.all(15), child: SizedBox(), )), - Positioned(child: Container( - height: 0, - width:0, - decoration: ShapeDecoration( - color:data.colorName =='red' ? Colors.redAccent : data.colorName =='orange' ? Colors.orangeAccent : data.colorName =='green' ? Colors.greenAccent : data.colorName == 'yellow' ? Colors.yellowAccent : Colors.grey, - shape: MessageBorder(), - - )),top:25, left: (MediaQuery.of(context).size.width * (double.parse(data.value) / 10)),) - + projectViewModel.isArabic + ? Positioned( + child: Container( + height: 0, + width: 0, + decoration: ShapeDecoration( + color: data.colorName == 'red' + ? Colors.redAccent + : data.colorName == 'orange' + ? Colors.orangeAccent + : data.colorName == 'green' + ? Colors.greenAccent + : data.colorName == 'yellow' + ? Colors.yellowAccent + : Colors.grey, + shape: MessageBorder(), + )), + top: 25, + right: (MediaQuery.of(context).size.width * (double.parse(data.value) / 10)), + ) + : Positioned( + child: Container( + height: 0, + width: 0, + decoration: ShapeDecoration( + color: data.colorName == 'red' + ? Colors.redAccent + : data.colorName == 'orange' + ? Colors.orangeAccent + : data.colorName == 'green' + ? Colors.greenAccent + : data.colorName == 'yellow' + ? Colors.yellowAccent + : Colors.grey, + shape: MessageBorder(), + )), + top: 25, + left: (MediaQuery.of(context).size.width * (double.parse(data.value) / 10)), + ) ], ), - ), Padding( - padding: EdgeInsets.only(top:10), - child: data.isValuesReversed == false ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - data.categoriesNames.category1, - fontSize: 12, - color: data.categoriesNames.category1== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category1== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category1== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category1== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - ), - AppText( - data.categoriesNames.category2, - fontSize: 12, - color: data.categoriesNames.category2== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category2== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category2== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category2== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category3, - fontSize: 12, - color: data.categoriesNames.category3== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category3== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category3== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category3== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category4, - fontSize: 12, - color: data.categoriesNames.category4== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category4== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category4== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category4== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category5, - fontSize: 12, - color: data.categoriesNames.category5== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category5== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category5== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category5== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - ], - ) : Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - data.categoriesNames.category5, - fontSize: 12, - color: data.categoriesNames.category5== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category5== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category5== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category5== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - ), - AppText( - data.categoriesNames.category4, - fontSize: 12, - color: data.categoriesNames.category4== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category4== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category4== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category4== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category3, - fontSize: 12, - color: data.categoriesNames.category3== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category3== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category3== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category3== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category2, - fontSize: 12, - color: data.categoriesNames.category2== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category2== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category2== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category2== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - AppText( - data.categoriesNames.category1, - fontSize: 12, - color: data.categoriesNames.category1== data.category && data.colorName=='red' ? Colors.redAccent : data.categoriesNames.category1== data.category && data.colorName=='orange' ? Colors.orangeAccent : data.categoriesNames.category1== data.category && data.colorName=='green' ? Colors.greenAccent : data.categoriesNames.category1== data.category && data.colorName=='yellow' ? Colors.yellow[900] : Colors.black - - ), - ], - )), - Padding( - padding: EdgeInsets.all(15), - child:Divider()) + padding: EdgeInsets.only(top: 10), + child: data.isValuesReversed == false + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText(data.categoriesNames.category1, + fontSize: 12, + color: data.categoriesNames.category1 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category2, + fontSize: 12, + color: data.categoriesNames.category2 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category3, + fontSize: 12, + color: data.categoriesNames.category3 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category4, + fontSize: 12, + color: data.categoriesNames.category4 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category5, + fontSize: 12, + color: data.categoriesNames.category5 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText(data.categoriesNames.category5, + fontSize: 12, + color: data.categoriesNames.category5 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category5 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category4, + fontSize: 12, + color: data.categoriesNames.category4 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category4 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category3, + fontSize: 12, + color: data.categoriesNames.category3 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category3 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category2, + fontSize: 12, + color: data.categoriesNames.category2 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category2 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + AppText(data.categoriesNames.category1, + fontSize: 12, + color: data.categoriesNames.category1 == data.category && data.colorName == 'red' + ? Colors.redAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'orange' + ? Colors.orangeAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'green' + ? Colors.greenAccent + : data.categoriesNames.category1 == data.category && data.colorName == 'yellow' + ? Colors.yellow[900] + : Colors.black), + ], + )), + Padding(padding: EdgeInsets.all(15), child: Divider()) ], ); - } } + class MessageBorder extends ShapeBorder { final bool usePadding; final bool reverse; - MessageBorder({this.usePadding = true, this.reverse =false}); + + MessageBorder({this.usePadding = true, this.reverse = false}); @override - EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: usePadding? 0 : 0); + EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: usePadding ? 0 : 0); @override Path getInnerPath(Rect rect, {TextDirection textDirection}) => null; @@ -175,17 +244,16 @@ class MessageBorder extends ShapeBorder { @override Path getOuterPath(Rect rect, {TextDirection textDirection}) { rect = Rect.fromPoints(rect.bottomRight, rect.bottomLeft - Offset(0, 0)); - if(!reverse) { + if (!reverse) { return Path() - ..addRRect( - RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))) + ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))) ..moveTo(rect.topCenter.dx - 10, rect.topCenter.dy) - ..relativeLineTo(10, -10)..relativeLineTo(10, 10) + ..relativeLineTo(10, -10) + ..relativeLineTo(10, 10) ..close(); - }else{ + } else { return Path() - ..addRRect( - RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))) + ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))) ..moveTo(rect.topCenter.dx, rect.topCenter.dy) ..relativeLineTo(10, 20) ..relativeLineTo(20, -20) @@ -198,4 +266,4 @@ class MessageBorder extends ShapeBorder { @override ShapeBorder scale(double t) => this; -} \ No newline at end of file +} From 69db41364f09e5240bcc52a326397c926a6dd1a8 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique" Date: Sun, 31 Oct 2021 14:39:18 +0300 Subject: [PATCH 57/60] icon fixs --- lib/config/config.dart | 4 +- .../ChildVaccines/new/child_vaccine_page.dart | 77 +++++++++++-------- lib/pages/livecare/clinic_timings_page.dart | 10 +-- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 6f05a414..bca5db17 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -15,8 +15,8 @@ const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/ChildVaccines/new/child_vaccine_page.dart b/lib/pages/ChildVaccines/new/child_vaccine_page.dart index 5f55401e..4d8b878c 100644 --- a/lib/pages/ChildVaccines/new/child_vaccine_page.dart +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -120,43 +120,54 @@ class _ChildPageState extends State with SingleTickerProviderS ], ), ), - InkWell( - onTap: () async { - await model.deleteBabyOrders(newChild: deleteBaby); + Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Icon( + Icons.arrow_forward, + size: 18, + ), + mHeight(12), + InkWell( + onTap: () async { + await model.deleteBabyOrders(newChild: deleteBaby); - deleteBaby.babyID = model.babyInformationModelList[index].babyID; + deleteBaby.babyID = model.babyInformationModelList[index].babyID; - await model.deleteBabyOrders(newChild: deleteBaby); - if (model.isDeleted) { - AppToast.showSuccessToast(message: TranslationBase.of(context).recordDeleted); - Navigator.pop(context, model.isDeleted); - } else { - //TODO handling error - } - }, - child: Container( - decoration: containerRadius(Colors.grey.withOpacity(0.2), 2000), - padding: EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8), - child: Row( - children: [ - Image.asset( - 'assets/images/new-design/garbage.png', - width: 16, - color: selectedColor, - ), - mWidth(8), - Text( - TranslationBase.of(context).deleteView, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - letterSpacing: -0.33, - color: selectedColor, - ), + await model.deleteBabyOrders(newChild: deleteBaby); + if (model.isDeleted) { + AppToast.showSuccessToast(message: TranslationBase.of(context).recordDeleted); + Navigator.pop(context, model.isDeleted); + } else { + //TODO handling error + } + }, + child: Container( + decoration: containerRadius(Colors.grey.withOpacity(0.2), 2000), + padding: EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8), + child: Row( + children: [ + Image.asset( + 'assets/images/new-design/garbage.png', + width: 16, + color: selectedColor, + ), + mWidth(8), + Text( + TranslationBase.of(context).deleteView, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.33, + color: selectedColor, + ), + ), + ], ), - ], + ), ), - ), + ], ), ], ), diff --git a/lib/pages/livecare/clinic_timings_page.dart b/lib/pages/livecare/clinic_timings_page.dart index 7e92a3c4..cd1652f2 100644 --- a/lib/pages/livecare/clinic_timings_page.dart +++ b/lib/pages/livecare/clinic_timings_page.dart @@ -78,18 +78,18 @@ class _LiveCarePatmentPageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - flex: 1, + flex: 2, child: Text( item.dayOfWeekStr, style: TextStyle( - fontSize: 13, - letterSpacing: -0.42, - fontWeight: FontWeight.w600, + fontSize: 18, + letterSpacing: -0.72, + fontWeight: FontWeight.bold, ), ), ), Expanded( - flex: 3, + flex: 4, child: Container( width: double.infinity, decoration: cardRadius(12), From 0853ecdc27e38dc34ae7ff00e0bb33b19e4c5a3e Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 31 Oct 2021 16:56:45 +0300 Subject: [PATCH 58/60] Body added --- assets/images/new/body/abdomin.svg | 3 + assets/images/new/body/chest.svg | 3 + assets/images/new/body/head.svg | 2 + assets/images/new/body/left_ankle.svg | 2 + assets/images/new/body/left_arm.svg | 3 + assets/images/new/body/left_ear.svg | 3 + assets/images/new/body/left_elbow.svg | 2 + assets/images/new/body/left_eye.svg | 2 + assets/images/new/body/left_foot.svg | 2 + assets/images/new/body/left_forearm.svg | 2 + assets/images/new/body/left_hand.svg | 2 + assets/images/new/body/left_knee.svg | 2 + assets/images/new/body/left_leg.svg | 2 + assets/images/new/body/left_soulder.svg | 2 + assets/images/new/body/left_thigh.svg | 2 + assets/images/new/body/left_wrist.svg | 2 + assets/images/new/body/mouth.svg | 3 + assets/images/new/body/neck.svg | 3 + assets/images/new/body/nose.svg | 3 + assets/images/new/body/pelvis.svg | 3 + assets/images/new/body/publs.svg | 2 + assets/images/new/body/right_ankle.svg | 2 + assets/images/new/body/right_arm.svg | 2 + assets/images/new/body/right_ear.svg | 3 + assets/images/new/body/right_elbow.svg | 2 + assets/images/new/body/right_eye.svg | 3 + assets/images/new/body/right_foot.svg | 2 + assets/images/new/body/right_forearm.svg | 2 + assets/images/new/body/right_hand.svg | 2 + assets/images/new/body/right_knee.svg | 2 + assets/images/new/body/right_leg.svg | 2 + assets/images/new/body/right_soulder.svg | 3 + assets/images/new/body/right_thigh.svg | 2 + assets/images/new/body/right_wrist.svg | 2 + lib/config/config.dart | 1 + lib/models/SmartWatch/HealthData.dart | 35 ++- lib/pages/BookAppointment/LaserBooking.dart | 128 ++++++++ .../components/SearchByClinic.dart | 42 ++- .../health_data_list.dart | 15 +- .../syncHealthData.dart | 274 ++++++++++++++++++ .../SmartWatchIntegrationService.dart | 32 +- pubspec.yaml | 3 + 42 files changed, 572 insertions(+), 37 deletions(-) create mode 100644 assets/images/new/body/abdomin.svg create mode 100644 assets/images/new/body/chest.svg create mode 100644 assets/images/new/body/head.svg create mode 100644 assets/images/new/body/left_ankle.svg create mode 100644 assets/images/new/body/left_arm.svg create mode 100644 assets/images/new/body/left_ear.svg create mode 100644 assets/images/new/body/left_elbow.svg create mode 100644 assets/images/new/body/left_eye.svg create mode 100644 assets/images/new/body/left_foot.svg create mode 100644 assets/images/new/body/left_forearm.svg create mode 100644 assets/images/new/body/left_hand.svg create mode 100644 assets/images/new/body/left_knee.svg create mode 100644 assets/images/new/body/left_leg.svg create mode 100644 assets/images/new/body/left_soulder.svg create mode 100644 assets/images/new/body/left_thigh.svg create mode 100644 assets/images/new/body/left_wrist.svg create mode 100644 assets/images/new/body/mouth.svg create mode 100644 assets/images/new/body/neck.svg create mode 100644 assets/images/new/body/nose.svg create mode 100644 assets/images/new/body/pelvis.svg create mode 100644 assets/images/new/body/publs.svg create mode 100644 assets/images/new/body/right_ankle.svg create mode 100644 assets/images/new/body/right_arm.svg create mode 100644 assets/images/new/body/right_ear.svg create mode 100644 assets/images/new/body/right_elbow.svg create mode 100644 assets/images/new/body/right_eye.svg create mode 100644 assets/images/new/body/right_foot.svg create mode 100644 assets/images/new/body/right_forearm.svg create mode 100644 assets/images/new/body/right_hand.svg create mode 100644 assets/images/new/body/right_knee.svg create mode 100644 assets/images/new/body/right_leg.svg create mode 100644 assets/images/new/body/right_soulder.svg create mode 100644 assets/images/new/body/right_thigh.svg create mode 100644 assets/images/new/body/right_wrist.svg create mode 100644 lib/pages/BookAppointment/LaserBooking.dart create mode 100644 lib/pages/medical/smart_watch_health_data/syncHealthData.dart diff --git a/assets/images/new/body/abdomin.svg b/assets/images/new/body/abdomin.svg new file mode 100644 index 00000000..c28cd70b --- /dev/null +++ b/assets/images/new/body/abdomin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/chest.svg b/assets/images/new/body/chest.svg new file mode 100644 index 00000000..77f603cb --- /dev/null +++ b/assets/images/new/body/chest.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/head.svg b/assets/images/new/body/head.svg new file mode 100644 index 00000000..5ec9c3f3 --- /dev/null +++ b/assets/images/new/body/head.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_ankle.svg b/assets/images/new/body/left_ankle.svg new file mode 100644 index 00000000..e7bf8080 --- /dev/null +++ b/assets/images/new/body/left_ankle.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_arm.svg b/assets/images/new/body/left_arm.svg new file mode 100644 index 00000000..6445b6be --- /dev/null +++ b/assets/images/new/body/left_arm.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/left_ear.svg b/assets/images/new/body/left_ear.svg new file mode 100644 index 00000000..402f5f20 --- /dev/null +++ b/assets/images/new/body/left_ear.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/left_elbow.svg b/assets/images/new/body/left_elbow.svg new file mode 100644 index 00000000..9e741679 --- /dev/null +++ b/assets/images/new/body/left_elbow.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_eye.svg b/assets/images/new/body/left_eye.svg new file mode 100644 index 00000000..add3c780 --- /dev/null +++ b/assets/images/new/body/left_eye.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_foot.svg b/assets/images/new/body/left_foot.svg new file mode 100644 index 00000000..c3f8de42 --- /dev/null +++ b/assets/images/new/body/left_foot.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_forearm.svg b/assets/images/new/body/left_forearm.svg new file mode 100644 index 00000000..7a8224b6 --- /dev/null +++ b/assets/images/new/body/left_forearm.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_hand.svg b/assets/images/new/body/left_hand.svg new file mode 100644 index 00000000..168d05c4 --- /dev/null +++ b/assets/images/new/body/left_hand.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_knee.svg b/assets/images/new/body/left_knee.svg new file mode 100644 index 00000000..5ff004f6 --- /dev/null +++ b/assets/images/new/body/left_knee.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_leg.svg b/assets/images/new/body/left_leg.svg new file mode 100644 index 00000000..352cf2b9 --- /dev/null +++ b/assets/images/new/body/left_leg.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_soulder.svg b/assets/images/new/body/left_soulder.svg new file mode 100644 index 00000000..8bd69c8c --- /dev/null +++ b/assets/images/new/body/left_soulder.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_thigh.svg b/assets/images/new/body/left_thigh.svg new file mode 100644 index 00000000..880e1da2 --- /dev/null +++ b/assets/images/new/body/left_thigh.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/left_wrist.svg b/assets/images/new/body/left_wrist.svg new file mode 100644 index 00000000..b99c3f1c --- /dev/null +++ b/assets/images/new/body/left_wrist.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/mouth.svg b/assets/images/new/body/mouth.svg new file mode 100644 index 00000000..1dd7ca76 --- /dev/null +++ b/assets/images/new/body/mouth.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/neck.svg b/assets/images/new/body/neck.svg new file mode 100644 index 00000000..e3c0d951 --- /dev/null +++ b/assets/images/new/body/neck.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/nose.svg b/assets/images/new/body/nose.svg new file mode 100644 index 00000000..1e08b591 --- /dev/null +++ b/assets/images/new/body/nose.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/pelvis.svg b/assets/images/new/body/pelvis.svg new file mode 100644 index 00000000..77d32820 --- /dev/null +++ b/assets/images/new/body/pelvis.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/publs.svg b/assets/images/new/body/publs.svg new file mode 100644 index 00000000..40909b35 --- /dev/null +++ b/assets/images/new/body/publs.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_ankle.svg b/assets/images/new/body/right_ankle.svg new file mode 100644 index 00000000..2eec1180 --- /dev/null +++ b/assets/images/new/body/right_ankle.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_arm.svg b/assets/images/new/body/right_arm.svg new file mode 100644 index 00000000..60a03321 --- /dev/null +++ b/assets/images/new/body/right_arm.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_ear.svg b/assets/images/new/body/right_ear.svg new file mode 100644 index 00000000..65de3b24 --- /dev/null +++ b/assets/images/new/body/right_ear.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/right_elbow.svg b/assets/images/new/body/right_elbow.svg new file mode 100644 index 00000000..0a58f385 --- /dev/null +++ b/assets/images/new/body/right_elbow.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_eye.svg b/assets/images/new/body/right_eye.svg new file mode 100644 index 00000000..4642c353 --- /dev/null +++ b/assets/images/new/body/right_eye.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/right_foot.svg b/assets/images/new/body/right_foot.svg new file mode 100644 index 00000000..5faa7b58 --- /dev/null +++ b/assets/images/new/body/right_foot.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_forearm.svg b/assets/images/new/body/right_forearm.svg new file mode 100644 index 00000000..fea91ddf --- /dev/null +++ b/assets/images/new/body/right_forearm.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_hand.svg b/assets/images/new/body/right_hand.svg new file mode 100644 index 00000000..b36dd80c --- /dev/null +++ b/assets/images/new/body/right_hand.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_knee.svg b/assets/images/new/body/right_knee.svg new file mode 100644 index 00000000..16a174cf --- /dev/null +++ b/assets/images/new/body/right_knee.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_leg.svg b/assets/images/new/body/right_leg.svg new file mode 100644 index 00000000..2cd6a760 --- /dev/null +++ b/assets/images/new/body/right_leg.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_soulder.svg b/assets/images/new/body/right_soulder.svg new file mode 100644 index 00000000..cb29dc98 --- /dev/null +++ b/assets/images/new/body/right_soulder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/new/body/right_thigh.svg b/assets/images/new/body/right_thigh.svg new file mode 100644 index 00000000..8d9ef522 --- /dev/null +++ b/assets/images/new/body/right_thigh.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/assets/images/new/body/right_wrist.svg b/assets/images/new/body/right_wrist.svg new file mode 100644 index 00000000..d54c14c8 --- /dev/null +++ b/assets/images/new/body/right_wrist.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index 6f05a414..9e17af68 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -325,6 +325,7 @@ const GET_COVID_DRIVETHRU_PROCEDURES_LIST = 'Services/Doctors.svc/REST/COVID19_G ///Smartwatch Integration Services const GET_PATIENT_LAST_RECORD = 'Services/Patients.svc/REST/Med_GetPatientLastRecord'; +const INSERT_PATIENT_HEALTH_DATA = 'Services/Patients.svc/REST/Med_InsertTransactions'; ///My Trackers const GET_DIABETIC_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; diff --git a/lib/models/SmartWatch/HealthData.dart b/lib/models/SmartWatch/HealthData.dart index f01c3bf8..d681f764 100644 --- a/lib/models/SmartWatch/HealthData.dart +++ b/lib/models/SmartWatch/HealthData.dart @@ -1,8 +1,37 @@ class healthData { int MedCategoryID; int MedSubCategoryID; - String Value; - String Notes; String MachineDate; + double Value; int TransactionsListID; -} + String Notes; + + healthData({ + this.MedCategoryID, + this.MedSubCategoryID, + this.MachineDate, + this.Value, + this.TransactionsListID, + this.Notes, + }); + + healthData.fromJson(Map json) { + MedCategoryID = json['MedCategoryID']; + MedSubCategoryID = json['MedSubCategoryID']; + MachineDate = json['MachineDate']; + Value = json['Value']; + TransactionsListID = json['TransactionsListID']; + Notes = json['Notes']; + } + + Map toJson() { + final Map data = new Map(); + data['MedCategoryID'] = this.MedCategoryID; + data['MedSubCategoryID'] = this.MedSubCategoryID; + data['MachineDate'] = this.MachineDate; + data['Value'] = this.Value; + data['TransactionsListID'] = this.TransactionsListID; + data['Notes'] = this.Notes; + return data; + } +} \ No newline at end of file diff --git a/lib/pages/BookAppointment/LaserBooking.dart b/lib/pages/BookAppointment/LaserBooking.dart new file mode 100644 index 00000000..b8691cf2 --- /dev/null +++ b/lib/pages/BookAppointment/LaserBooking.dart @@ -0,0 +1,128 @@ +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class LaserBooking extends StatefulWidget { + @override + _LaserBookingState createState() => _LaserBookingState(); +} + +class _LaserBookingState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowDecPage: false, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: "Laser", + body: Container( + child: Column( + children: [ + HumanAnatomy(), + ], + ), + )); + } +} + +class HumanAnatomy extends StatefulWidget { + final ValueChanged onChanged; + + const HumanAnatomy({Key key, this.onChanged}) : super(key: key); + + @override + _HumanAnatomyState createState() => new _HumanAnatomyState(); +} + +class _HumanAnatomyState extends State { + var _bodyPartList = []; + + @override + void initState() { + super.initState(); + if (mounted) { + _publishSelection(_bodyPartList); + } + } + + @override + Widget build(BuildContext context) { + return humanAnatomy(); + } + + Widget humanAnatomy() { + return Container( + width: 320.0, + height: 560.0, + child: SizedBox( + child: Stack( + children: [ + bodyPart("assets/images/new/body/head.svg", "Head", 0.0, 0.0, 0.0, 70.0), + bodyPart("assets/images/new/body/left_ear.svg", "leftEar", 32.0, 50.0, 0.0, 20.0), + bodyPart("assets/images/new/body/right_ear.svg", "rightEar", 32.0, 0.0, 50.0, 20.0), + bodyPart("assets/images/new/body/left_eye.svg", "LeftEye", 22.0, 20.0, 0.0, 10.0), + bodyPart("assets/images/new/body/right_eye.svg", "rightEye", 22.0, 0.0, 20.0, 10.0), + bodyPart("assets/images/new/body/nose.svg", "Nose", 25.0, 0.0, 0.0, 20.0), + bodyPart("assets/images/new/body/mouth.svg", "Mouth", 48.0, 0.0, 0.0, 10.0), + bodyPart("assets/images/new/body/neck.svg", "Neck", 58.0, 0.0, 0.0, 40.0), + bodyPart("assets/images/new/body/chest.svg", "Chest", 93.0, 0.0, 0.0, 95.0), + bodyPart("assets/images/new/body/abdomin.svg", "Abdomin", 175.0, 0.0, 0.0, 65.0), + bodyPart("assets/images/new/body/pelvis.svg", "Pelvis", 225.0, 0.0, 0.0, 50.0), + bodyPart("assets/images/new/body/publs.svg", "Publs", 275.0, 0.0, 0.0, 15.0), + bodyPart("assets/images/new/body/left_soulder.svg", "leftSoulder", 90.0, 105.0, 0.0, 50.0), + bodyPart("assets/images/new/body/right_soulder.svg", "rightSoulder", 89.0, 0.0, 110.0, 50.0), + bodyPart("assets/images/new/body/left_arm.svg", "leftArm", 120.0, 145.0, 0.0, 70.0), + bodyPart("assets/images/new/body/right_arm.svg", "rightArm", 118.0, 0.0, 142.0, 70.0), + bodyPart("assets/images/new/body/left_elbow.svg", "leftElbow", 172.0, 172.0, 0.0, 39.0), + bodyPart("assets/images/new/body/right_elbow.svg", "rightElbow", 170.0, 0.0, 170.0, 40.0), + bodyPart("assets/images/new/body/left_forearm.svg", "leftForearm", 195.0, 190.0, 0.0, 54.0), + bodyPart("assets/images/new/body/right_forearm.svg", "rightForearm", 195.0, 0.0, 190.0, 54.0), + bodyPart("assets/images/new/body/left_wrist.svg", "leftWrist", 238.0, 220.0, 0.0, 23.0), + bodyPart("assets/images/new/body/right_wrist.svg", "rightWrist", 238.0, 0.0, 220.0, 23.0), + bodyPart("assets/images/new/body/left_hand.svg", "leftHand", 250.0, 250.0, 0.0, 60.0), + bodyPart("assets/images/new/body/right_hand.svg", "rightHand", 250.0, 0.0, 250.0, 60.0), + bodyPart("assets/images/new/body/left_thigh.svg", "leftThigh", 242.0, 63.0, 0.0, 138.0), + bodyPart("assets/images/new/body/right_thigh.svg", "rightThigh", 242.0, 0.0, 63.0, 138.0), + bodyPart("assets/images/new/body/left_knee.svg", "leftKnee", 360.0, 68.0, 0.0, 48.0), + bodyPart("assets/images/new/body/right_knee.svg", "rightKnee", 360.0, 0.0, 68.0, 48.0), + bodyPart("assets/images/new/body/left_leg.svg", "leftLeg", 395.0, 64.0, 0.0, 105.0), + bodyPart("assets/images/new/body/right_leg.svg", "rightLeg", 393.0, 0.0, 65.0, 106.0), + bodyPart("assets/images/new/body/left_ankle.svg", "leftAnkle", 495.0, 64.0, 0.0, 25.0), + bodyPart("assets/images/new/body/right_ankle.svg", "rightAnkle", 493.0, 0.0, 68.0, 25.0), + bodyPart("assets/images/new/body/left_foot.svg", "leftFoot", 510.0, 80.0, 0.0, 60.0), + bodyPart("assets/images/new/body/right_foot.svg", "rightFoot", 508.0, 0.0, 83.0, 56.0), + ], + ), + ), + ); + } + + Widget bodyPart(String svgPath, String svgName, double marginTop, double marginRight, double marginLeft, double height) { + Color _svgColor = _bodyPartList.contains(svgName) ? Colors.redAccent : null; + final Widget bodyPartSvg = new SvgPicture.asset(svgPath, semanticsLabel: svgName, color: _svgColor); + return Container( + margin: EdgeInsets.only(top: marginTop, right: marginRight, left: marginLeft), + height: height, + alignment: Alignment.topCenter, + child: GestureDetector( + onTap: () { + setState(() { + if (_bodyPartList.contains(svgName)) { + _bodyPartList.remove(svgName); + } else { + _bodyPartList.add(svgName); + // _bodyPartList.forEach((e) => print(e)); + } + }); + }, + child: bodyPartSvg), + ); + } + + void _publishSelection(List _bodyPartList) { + if (widget.onChanged != null) { + widget.onChanged(_bodyPartList); + } + } +} diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 147cb9f9..f250bc3f 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -8,6 +8,7 @@ import 'package:diplomaticquarterapp/models/Appointments/SearchInfoModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/LaserBooking.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; @@ -176,9 +177,10 @@ class _SearchByClinicState extends State { ), ], ), - - Container(child: inputWidget("Age", "", ageController),margin: EdgeInsets.only(left: 20, right: 20),), - + Container( + child: inputWidget("Age", "", ageController), + margin: EdgeInsets.only(left: 20, right: 20), + ), ], ), Padding( @@ -421,15 +423,15 @@ class _SearchByClinicState extends State { prefixIcon: prefix == null ? null : Text( - "+" + prefix, - style: TextStyle( - fontSize: 14, - height: 21 / 14, - fontWeight: FontWeight.w500, - color: Color(0xff2E303A), - letterSpacing: -0.56, - ), - ), + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), contentPadding: EdgeInsets.zero, border: InputBorder.none, focusedBorder: InputBorder.none, @@ -446,7 +448,6 @@ class _SearchByClinicState extends State { ); } - void openDropdown(GlobalKey key) { GestureDetector detector; void searchForGestureDetector(BuildContext element) { @@ -537,6 +538,8 @@ class _SearchByClinicState extends State { searchInfo.date = DateTime.now(); navigateToDentalComplaints(context, searchInfo); + } else if (dropdownValue.split("-")[0] == "253") { + navigateToLaserClinic(context); } else if (dropdownValue.split("-")[1] == "true" // && authProvider.isLogin && // authUser.patientType == 1 @@ -625,6 +628,19 @@ class _SearchByClinicState extends State { }); } + Future navigateToLaserClinic(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: LaserBooking(), + ), + ).then((value) { + setState(() { + dropdownValue = null; + }); + }); + } + Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { isProjectLoaded = false; Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))) diff --git a/lib/pages/medical/smart_watch_health_data/health_data_list.dart b/lib/pages/medical/smart_watch_health_data/health_data_list.dart index f43a6e63..80a12cca 100644 --- a/lib/pages/medical/smart_watch_health_data/health_data_list.dart +++ b/lib/pages/medical/smart_watch_health_data/health_data_list.dart @@ -1,8 +1,8 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/Steps/stepsTracker.dart'; import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/distance/distanceTracker.dart'; import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/syncHealthData.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -64,20 +64,10 @@ class _HealthDataListState extends State { ), ), ), - bottomSheet: Container( - color: Colors.white, - child: Padding( - padding: const EdgeInsets.all(20.0), - child: DefaultButton(TranslationBase.of(context).syncHealthData, () { - print("ReadLast"); - // readLast(); - }), - ), - ), + bottomSheet: syncHealthDataButton(), ); } - List myOptionsList(BuildContext context) { List medical = List(); @@ -123,7 +113,6 @@ class _HealthDataListState extends State { return medical; } - // void readLast() async { // print("ReadLast"); // final result = await FitKit.readLast(DataType.DISTANCE); diff --git a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart new file mode 100644 index 00000000..47be3c5f --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart @@ -0,0 +1,274 @@ +import 'package:collection/collection.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/HealthData.dart'; +import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchIntegrationService.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; +import 'package:fit_kit/fit_kit.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class syncHealthDataButton extends StatefulWidget { + double marginTop; + + double hight; + + double minWidth; + + syncHealthDataButton({this.marginTop, this.hight, this.minWidth}); + + @override + _syncHealthDataButtonState createState() => _syncHealthDataButtonState(); +} + +class _syncHealthDataButtonState extends State { + List dataTypes = List(); + + List Med_InsertTransactionsInputsList = new List(); + List Med_InsertTransactionsInputsList2 = new List(); + + List sleepDataList = new List(); + + List healthDataList = new List(); + + int TransactionsListID = 1; + + int MedCategoryID = 0; + + @override + void initState() { + dataTypes.add(DataType.DISTANCE); + dataTypes.add(DataType.STEP_COUNT); + dataTypes.add(DataType.HEART_RATE); + // dataTypes.add(DataType.SLEEP); + // dataTypes.add(DataType.ENERGY); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(20.0), + child: DefaultButton(TranslationBase.of(context).syncHealthData, () { + print("ReadAll"); + readAll(); + }), + ), + ); + } + + void readAll() async { + TransactionsListID = 1; + var MedSubCategoryID = 0; + double value = 0.0; + + GifLoaderDialogUtils.showMyDialog(context); + Med_InsertTransactionsInputsList.clear(); + var date; + var differenceInHours; + String strDifferenceInHours; + var differenceInMinutes; + String strDifferenceInMinutes; + var today = DateTime.now(); + var yearNum = DateFormat('y').format(today).toString(); + + var firstDayOfTheYear = DateTime.parse(yearNum + "-" + "01" + "-" + "01"); + + if (await FitKit.requestPermissions(dataTypes)) { + for (DataType type in dataTypes) { + final results = await FitKit.read( + type, + dateFrom: firstDayOfTheYear, + dateTo: DateTime.now(), + limit: 1000500, + ); + + if (type == DataType.DISTANCE) { + MedCategoryID = 7; + } else if (type == DataType.STEP_COUNT) { + MedCategoryID = 6; + } else if (type == DataType.HEART_RATE) { + MedCategoryID = 3; + } + + results.forEach((result) { + // print("in forEach"); + date = result.dateTo; + if (result.value.runtimeType.toString() == "int") { + value = double.parse(result.value.toString()); + } else { + value = result.value; + } + + MedSubCategoryID = 0; + + if (MedCategoryID == 4) { + differenceInHours = null; + var sleepDate = result.dateFrom.toString().substring(0, 10); + + DateTime dateFrom = result.dateFrom; + DateTime dateTo = result.dateTo; + + differenceInMinutes = dateTo.difference(dateFrom).inMinutes; + differenceInMinutes > 59 ? differenceInHours = differenceInMinutes / 60 : differenceInMinutes = differenceInMinutes; + + if (differenceInHours != null && differenceInHours != 0) { + differenceInHours = differenceInHours.toInt(); + differenceInMinutes = differenceInMinutes % 60; + + differenceInHours < 10 ? strDifferenceInHours = "0" + differenceInHours.toString() : strDifferenceInHours = differenceInHours.toString(); + } else { + strDifferenceInHours = "00"; + differenceInHours = 00; + } + differenceInMinutes < 10 ? strDifferenceInMinutes = "0" + differenceInMinutes.toString() : strDifferenceInMinutes = differenceInMinutes.toString(); + + sleepDate = DateTime.parse(sleepDate + " " + strDifferenceInHours + ":" + strDifferenceInMinutes + ":" + "00.00").toString(); + String hours = sleepDate.substring(11, sleepDate.indexOf(":")); + print(hours); + + String minutes = sleepDate.substring(sleepDate.indexOf(":") + 1, sleepDate.indexOf(":") + 3); + print(minutes); + + if (value == 0 || value == 109) { + print("in Bed"); + MedSubCategoryID = 1; + value = double.parse(hours + "." + minutes); + print("value"); + print(value); + } else if (value == 1 || value == 110) { + print("Sleep"); + MedSubCategoryID = 2; + value = double.parse(hours + "." + minutes); + print("value"); + print(value); + } + } + date = DateUtil.convertDateToString(date); + Med_InsertTransactionsInputsList.add( + healthData(MedCategoryID: MedCategoryID, MedSubCategoryID: MedSubCategoryID, MachineDate: date, Value: value, TransactionsListID: TransactionsListID++, Notes: "")); + }); + } + } + getAllHealthDataLists(); + } + + void getAllHealthDataLists() { + var totalSteps = 0.0; + var totalDistance = 0.0; + // double totalCalories = 0.0 ; + double totalHeartRate = 0.0; + double avgTotalHeartRate = 0.0; + var counter = 0; + List data = []; + TransactionsListID = 1; + + DateTime date; + sleepDataList.clear(); + + Med_InsertTransactionsInputsList.forEach((result) { + data.add(result.toJson()); + }); + + Med_InsertTransactionsInputsList2.clear(); + + var newMap = groupBy(data, (obj) => DateUtil.convertStringToDate(obj['MachineDate']).toString().substring(0, 10)); + + newMap.forEach((key, value) { + totalSteps = 0.0; + totalDistance = 0.0; + totalHeartRate = 0.0; + avgTotalHeartRate = 0.0; + counter = 0; + + date = DateTime.parse(key); + + value.forEach((element) { + if (element['MedCategoryID'] == 6) { + MedCategoryID = 6; + + totalSteps += element['Value']; + } else if (element['MedCategoryID'] == 7) { + MedCategoryID = 7; + // to convert from meter to km + totalDistance += (element['Value'] * 0.001); + } else if (element['MedCategoryID'] == 3) { + print("HeartRate"); + MedCategoryID = 3; + counter++; + totalHeartRate += element['Value']; + } else if (element['MedCategoryID'] == 4) { + print("sleeeeep"); + sleepDataList.add(new healthData( + MedCategoryID: 4, + MedSubCategoryID: element['MedSubCategoryID'], + MachineDate: DateUtil.convertDateToString(date), + Value: element['Value'], + TransactionsListID: TransactionsListID++, + Notes: "")); + + Med_InsertTransactionsInputsList2.add(new healthData( + MedCategoryID: 4, + MedSubCategoryID: element['MedSubCategoryID'], + MachineDate: DateUtil.convertDateToString(date), + Value: element['Value'], + TransactionsListID: TransactionsListID++, + Notes: "")); + } + // else if(element['MedCategoryID'] == 8){ + // + // totalCalories += element['Value'] ; + // } + }); + + if (counter == 0) { + counter = 1; + } + if (totalHeartRate == 0) { + avgTotalHeartRate = 0; + } else { + avgTotalHeartRate = totalHeartRate / counter; + } + + Med_InsertTransactionsInputsList2.add( + new healthData(MedCategoryID: 6, MedSubCategoryID: 0, MachineDate: DateUtil.convertDateToString(date), Value: totalSteps, TransactionsListID: TransactionsListID++, Notes: "")); + Med_InsertTransactionsInputsList2.add( + new healthData(MedCategoryID: 7, MedSubCategoryID: 0, MachineDate: DateUtil.convertDateToString(date), Value: totalDistance, TransactionsListID: TransactionsListID++, Notes: "")); + Med_InsertTransactionsInputsList2.add( + new healthData(MedCategoryID: 3, MedSubCategoryID: 0, MachineDate: DateUtil.convertDateToString(date), Value: avgTotalHeartRate, TransactionsListID: TransactionsListID++, Notes: "")); + + // Med_InsertTransactionsInputsList2.add(new healthData(MedCategoryID: 8 , MedSubCategoryID: 0 , MachineDate: DateUtil.convertDateToStringWithBackSlash(date) , Value: totalCalories , TransactionsListID: TransactionsListID++ , Notes: "")); + }); + + GifLoaderDialogUtils.hideDialog(context); + + AlertDialogBox dialog = new AlertDialogBox( + context: context, + confirmMessage: TranslationBase.of(context).alreadySynced, + okText: TranslationBase.of(context).ok, + okFunction: () => { + AlertDialogBox.closeAlertDialog(context), + }, + ); + + dialog.showAlertDialog(context); + } + + addInsertTransactionsInputsList() { + if (Med_InsertTransactionsInputsList2.isNotEmpty) { + SmartWatchIntegrationService service = new SmartWatchIntegrationService(); + service.insertPatientHealthData(Med_InsertTransactionsInputsList2, context).then((res) { + print(res); + }).catchError((err) { + print(err); + }); + } else { + return; + } + } +} diff --git a/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart b/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart index 3bfe62e3..459c0e83 100644 --- a/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart +++ b/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/HealthData.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; @@ -18,8 +19,7 @@ class SmartWatchIntegrationService extends BaseService { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } @@ -42,13 +42,29 @@ class SmartWatchIntegrationService extends BaseService { dynamic localRes; - await baseAppClient.post(GET_PATIENT_LAST_RECORD, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_PATIENT_LAST_RECORD, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); + } + Future insertPatientHealthData(List healthData, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = { + "Med_InsertTransactionsInputsList": healthData, + }; + dynamic localRes; + await baseAppClient.post(INSERT_PATIENT_HEALTH_DATA, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); } } diff --git a/pubspec.yaml b/pubspec.yaml index 49700d97..c871fdb2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,8 @@ dependencies: #Dependency Injection get_it: ^4.0.2 + #Google Fit & Apple HealthKit + fit_kit: ^1.1.2 #chart fl_chart: ^0.12.3 @@ -250,6 +252,7 @@ flutter: - assets/images/new/services/ - assets/images/new/appointment-rating/ - assets/images/new/payment/ + - assets/images/new/body/ fonts: - family: WorkSans From 668d725b25a3f90690c0e90cf6f535dc0ab8beb5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 31 Oct 2021 17:06:25 +0300 Subject: [PATCH 59/60] Laser booking --- lib/pages/BookAppointment/LaserBooking.dart | 1 - lib/pages/BookAppointment/components/SearchByClinic.dart | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/BookAppointment/LaserBooking.dart b/lib/pages/BookAppointment/LaserBooking.dart index b8691cf2..f1acaf2c 100644 --- a/lib/pages/BookAppointment/LaserBooking.dart +++ b/lib/pages/BookAppointment/LaserBooking.dart @@ -112,7 +112,6 @@ class _HumanAnatomyState extends State { _bodyPartList.remove(svgName); } else { _bodyPartList.add(svgName); - // _bodyPartList.forEach((e) => print(e)); } }); }, diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index f250bc3f..63e84e96 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -539,7 +539,8 @@ class _SearchByClinicState extends State { navigateToDentalComplaints(context, searchInfo); } else if (dropdownValue.split("-")[0] == "253") { - navigateToLaserClinic(context); + // navigateToLaserClinic(context); + callDoctorsSearchAPI(); } else if (dropdownValue.split("-")[1] == "true" // && authProvider.isLogin && // authUser.patientType == 1 From d486b76116a34a0c760b94068a796023e5e7c17d Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 31 Oct 2021 17:17:25 +0200 Subject: [PATCH 60/60] fix merge issue --- lib/config/config.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index cbe90077..1b09e86f 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -15,7 +15,7 @@ const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; // const BASE_URL = 'https://hmgwebservices.com/'; // const BASE_URL = 'https://uat.hmgwebservices.com/'; const BASE_URL = 'https://hmgwebservices.com/';